package com.binguo.api.service;

import com.alibaba.fastjson.JSONObject;
import com.binguo.api.baidu.BaiduRecUtil;
import com.binguo.api.baidu.CorrectService;
import com.binguo.api.businessmodel.ProductImgDetailModel;
import com.binguo.api.businessmodel.ProductImgModel;
import com.binguo.api.form.IntranetOrderForm;
import com.binguo.api.form.IntranetOrderImgForm;
import com.binguo.api.response.api.BaseChargeResp;
import com.binguo.api.schedule.DataLoadService;
import com.binguo.api.service.api.ShopApiInterface;
import com.binguo.common.enums.CardType;
import com.binguo.common.enums.PayStatus;
import com.binguo.common.enums.PayType;
import com.binguo.common.enums.RefundStatus;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.paymodel.ThreadManager;
import com.binguo.common.paymodel.YilingPayResult;
import com.binguo.common.util.ImageBase64Util;
import com.binguo.common.util.JsonUtil;
import com.binguo.common.util.PriceUtil;
import com.binguo.entity.DiscountOrderDetail;
import com.binguo.model.api.dto.OrderDTO;
import com.binguo.model.api.dto.OrderItemDTO;
import com.binguo.model.api.vo.OrderVO;
import com.binguo.model.api.vo.ShangMiOrderVO;
import com.binguo.model.mapper.*;
import com.binguo.model.model.*;
import com.binguo.model.repository.*;
import com.binguo.service.*;
import com.binguo.thirdPay.ZhenYuanPay.ZhenYuanPay;
import com.binguo.thirdPay.aiBao.AiBaoPay;
import com.binguo.thirdPay.caoGenYaoPay.CaoGenYaoPay;
import com.binguo.thirdPay.diKeYWPay.DiKeYWPay;
import com.binguo.thirdPay.hzShiMing.HZShiMingService;
import com.binguo.thirdPay.hzShiMing.SrPayService;
import com.binguo.thirdPay.jinHuaSZFPay.JinHuaSZFPayService;
import com.binguo.thirdPay.jinQiao.JinQiaoPayCardItem;
import com.binguo.thirdPay.jinQiao.JinQiaoPayController;
import com.binguo.thirdPay.wuZhenPay.WuZhenPayService;
import com.binguo.thirdPay.zy.ZytkService;
import com.binguo.transfer.OrderVOTransfer;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.binguo.common.exception.ErrorCode.*;

/**
 * Created by haibang on 18/6/12.
 */
@Service
public class ApiOrderService {
    private static Logger logger = LoggerFactory.getLogger(ApiOrderService.class);

    private final Integer wuJinShopId = 135;

    @Autowired
    BinguoOrderRepository binguoOrderRepository;

    @Autowired
    OrderItemRepository orderItemRepository;

    @Autowired
    ShopRepository shopRepository;

    @Autowired
    OrderService orderService;

    @Autowired
    CustomerService customerService;

    @Autowired
    ShopService shopService;

    @Resource
    BinguoOrderMapper binguoOrderMapper;

    @Resource
    DiscountOrderMapper discountOrderMapper;

    @Autowired
    OrderVOTransfer orderVOTransfer;

    @Autowired
    PayCardRepository payCardRepository;

    @Autowired
    CashierDeskRepository cashierDeskRepository;

    @Autowired
    CustomerRepository customerRepository;

    @Autowired
    ShopShimingkaDiscountRepository shopShimingkaDiscountRepository;

    @Autowired
    WXPayService wxPayService;

    @Autowired
    AliPayService aliPayService;

    @Autowired
    ProductService productService;

    @Autowired
    WXServerPayService wxServerPayService;

    @Autowired
    NewDiscountService discountService;

    @Autowired
    ZytkService zytkService;

    @Autowired
    SrPayService srPayService;

    @Autowired
    InitInfoRepository initInfoRepository;

    @Autowired
    HZShiMingService hzShiMingService;

    @Autowired
    ShimingkaOrderRepository shimingkaOrderRepository;

    @Autowired
    CashierDeskWuzhenRepository cashierDeskWuzhenRepository;

    @Autowired
    WuZhenPayService wuZhenPayService;

    @Autowired
    YpCardRepository ypCardRepository;

    @Autowired
    ShopPackageDiscountRepository shopPackageDiscountRepository;

    @Autowired
    AiBaoPay aiBaoPay;

    @Autowired
    ShopMenjinOrderRepository shopMenjinOrderRepository;

    @Resource
    private CustomerExtendMapper customerExtendMapper;
    @Autowired
    private AliServerPayService aliServerPayService;

    @Autowired
    StatisticOrderService statisticOrderService;

    @Resource
    ZhenYuanPay zhenYuanPay;

    @Resource
    DiKeYWPay diKeYWPay;

    @Resource
    ShopZyOrderRepository shopZyOrderRepository;

    @Resource
    ShopZyParamRepository shopZyParamRepository;

    @Resource
    BaiduRecUtil baiduRecUtil;

    @Autowired
    CaoGenYaoPay caoGenYaoPay;

    @Resource
    ProductPriceMapper productPriceMapper;

    @Autowired
    RenShouTangService renShouTangService;

    @Autowired
    MenjinBindingRepository menjinBindingRepository;

    @Autowired
    CustomerGroupCashierDeskRepository customerGroupCashierDeskRepository;

    @Autowired
    ShopCaogenyaoConfigRepository shopCaogenyaoConfigRepository;


    @Resource
    RedisLockService redisLockService;

    @Resource
    JinHuaSZFPayService jinHuaSZFPayService;

    @Resource
    CorrectService correctService;

    @Resource
    CashierDeskMapper cashierDeskMapper;

    @Autowired
    RuiJingService ruiJingService;

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    private static SimpleDateFormat dbCompareDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");

    /**
     * 检测会员等是否允许
     *
     * @param orderDTO
     * @return
     */
    public boolean isCustomerGroupNotAllow(OrderDTO orderDTO) {

        if (DataLoadService.shopIdList != null) {
            if (orderDTO.getCustomerId() != null && orderDTO.getCustomerId() > 0) {
                if (DataLoadService.cashierDeskBranchMap != null) {
                    Integer branchId = DataLoadService.cashierDeskBranchMap.get(orderDTO.getCashierDeskId());

                    if (branchId != null && branchId > 0) {
                        List<Integer> customerGroupList =
                                DataLoadService.branchCustomerGroupListMap.get(branchId);

                        if (customerGroupList != null && customerGroupList.size() > 0) {

                            Integer userGroupId = null;
                            if (orderDTO.getCustomerGroupID() == null || orderDTO.getCustomerGroupID() == 0) {
                                Condition condition = new Condition(CustomerExtend.class);
                                condition.or().andEqualTo("shopId", orderDTO.getShopId())
                                        .andEqualTo("customerId", orderDTO.getCustomerId());
                                List<CustomerExtend> customerExtendList = customerExtendMapper.selectByCondition(condition);

                                if (customerExtendList != null && customerExtendList.size() > 0) {
                                    CustomerExtend customerExtend = customerExtendList.get(0);

                                    if (customerExtend.getIsAudit() == 0){
                                        throw new ServiceException(CUSTOMER_NOT_EXIST);
                                    }

                                    userGroupId = customerExtend.getGroupId();

                                    orderDTO.setCustomerGroupID(userGroupId);
                                }
                            }else {
                                userGroupId = orderDTO.getCustomerGroupID();
                            }



                            if (!customerGroupList.contains(userGroupId)) {
                                return true;
                            }
                        }
                    }
                }
            }
        }

        return false;
    }

    public OrderVO create(OrderDTO orderDTO, String ip) throws Exception {
        logger.info("orderinfo=" + JsonUtil.toJson(orderDTO));
        //logger.info("orderinfo===" + JsonUtil.toJson(orderDTO));

        if (orderDTO.getItems() == null || orderDTO.getItems().size() == 0) {
            throw new ServiceException("参数错误");
        }
        Integer shopPayConfigId = null;

        Integer branchId = null;

        if (branchId == null) {
            if (DataLoadService.cashierDeskBranchMap != null) {
                branchId = DataLoadService.cashierDeskBranchMap.get(orderDTO.getCashierDeskId());
            }

            if (branchId == null || branchId == 0) {
                CashierDesk cashierDesk = cashierDeskMapper.selectByPrimaryKey(orderDTO.getCashierDeskId());
                if (cashierDesk != null) {
                    branchId = cashierDesk.getBranchid();
                }

                if (branchId == null || branchId == 0) {
                    Branch branch = DataLoadService.branchListMap.get(cashierDesk.getShopid());
                    if (branch != null) {
                        branchId = branch.getBranchId();
                    }
                }
            }
        }

        if (DataLoadService.shopPayConfigListMap != null) {
            List<ShopPayConfig> shopPayConfigList =
                    DataLoadService.shopPayConfigListMap.get(orderDTO.getShopId());

            if (shopPayConfigList != null) {
                boolean enable = false;

                try {
                    Date now = new Date();
                    now = formatter.parse(formatter.format(now));
                    logger.info("now={}", now);

                    Integer tempShopPayConfigId = null;
                    for (ShopPayConfig shopPayConfig : shopPayConfigList) {
                        logger.info("shopPayConfig.startTime={}", shopPayConfig.getStartTime());
                        logger.info("shopPayConfig.endTime={}", shopPayConfig.getEndTime());

                        if (now.after(shopPayConfig.getStartTime()) && shopPayConfig.getEndTime().after(now)) {
                            enable = true;
                            if (shopPayConfig.getBranchId() != null && shopPayConfig.getBranchId().intValue() == branchId.intValue()) {
                                shopPayConfigId = shopPayConfig.getId();
                                logger.info("shopPayConfigListMap===true");
                                break;
                            }

                            if (shopPayConfig.getBranchId() == null) {
                                tempShopPayConfigId = shopPayConfig.getId();
                            }
                        }
                    }

                    if (!enable) {
                        logger.info("shopPayConfigListMap===false");
                        throw new ServiceException("时间未开放");
                    }

                    if (shopPayConfigId == null && tempShopPayConfigId != null) {
                        shopPayConfigId = tempShopPayConfigId;
                    }

                } catch (ParseException e) {
                    e.printStackTrace();
                    throw new ServiceException("时间未开放");
                }
            }
        }

        Integer limitCosumeCount = null;
        if (DataLoadService.shopPayCashierDeskConfigListMap != null) {
            List<ShopPayCashierDeskConfig> shopPayCashierDeskConfigList =
                    DataLoadService.shopPayCashierDeskConfigListMap.get(orderDTO.getShopId());
            if (shopPayCashierDeskConfigList != null && orderDTO.getCashierDeskId() != null) {
                Integer tempLimitCosumeCount = null;
                for (ShopPayCashierDeskConfig shopPayCashierDeskConfig : shopPayCashierDeskConfigList) {
                    if (shopPayConfigId != null && shopPayCashierDeskConfig.getShopPayConfigId() != null &&
                            shopPayConfigId.intValue() == shopPayCashierDeskConfig.getShopPayConfigId().intValue()) {
                        if (shopPayCashierDeskConfig.getCashierDeskId() == null) {
                            limitCosumeCount = shopPayCashierDeskConfig.getConsumeCountLimit();
                            break;
                        }
                        if (shopPayCashierDeskConfig.getCashierDeskId() != null && shopPayCashierDeskConfig.getCashierDeskId().intValue() == orderDTO.getCashierDeskId().intValue()) {
                            limitCosumeCount = shopPayCashierDeskConfig.getConsumeCountLimit();
                            break;
                        }
                    }else {
                        if (shopPayCashierDeskConfig.getShopPayConfigId() == null) {
                            if (shopPayCashierDeskConfig.getCashierDeskId() != null && shopPayCashierDeskConfig.getCashierDeskId().intValue() == orderDTO.getCashierDeskId().intValue()) {
                                limitCosumeCount = shopPayCashierDeskConfig.getConsumeCountLimit();
                                shopPayConfigId = 0;
                                break;
                            }else {
                                if (shopPayCashierDeskConfig.getCashierDeskId() == null) {
                                    tempLimitCosumeCount = shopPayCashierDeskConfig.getConsumeCountLimit();
//                                    shopPayConfigId = 0;
//                                    break;
                                }
                            }
                        }
                    }
                }

                if (limitCosumeCount == null && tempLimitCosumeCount != null) {
                    limitCosumeCount = tempLimitCosumeCount;
                }
            }
        }
        orderDTO.setConsumeLimitCount(limitCosumeCount);
        orderDTO.setShopPayConfigId(shopPayConfigId);



        if (orderDTO.getProductOrderNo() != null) {
            if (StringUtils.hasText(orderDTO.getProductOrderNo())) {
                ProductImgModel productImgModel =
                        baiduRecUtil.getProductImgFromCache(orderDTO.getProductOrderNo());

                if (productImgModel != null) {
                    String productOrderImgUrl = productImgModel.getImgUrl();

                    orderDTO.setProductOrderUrl(productOrderImgUrl);

                    Map<String, ProductImgDetailModel> seqProductImgDetailModelMap = new HashMap<>();

                    for (ProductImgDetailModel productImgDetailModel : productImgModel.getItemList()) {
                        seqProductImgDetailModelMap.put(productImgDetailModel.getSeq().toString(), productImgDetailModel);
                    }



                    for (OrderItemDTO orderItemDTO : orderDTO.getItems()) {
                        logger.info("===============start =====orderItemDTO.getChange()====" + orderItemDTO.getChange());
                        if (orderItemDTO.getChange() != null && orderItemDTO.getChange().equals("1")) {
                            if (orderItemDTO.getProductId() == null || orderItemDTO.getProductId().intValue() <= 0) {
                                //无菜品Id处理
                                ProductImgDetailModel productImgDetailModel = seqProductImgDetailModelMap.get(orderItemDTO.getSeq());



                                Integer newProductId = correctService.handleNoSettedProduct(orderDTO.getProductOrderNo(),
                                        orderItemDTO, productImgDetailModel, branchId, orderDTO.getShopId());

                                logger.info("===============start =====newProductId====" + newProductId);
                                if (newProductId != null) {
                                    orderItemDTO.setProductId(newProductId);
                                }
                            }
                        }else {
                            if (orderItemDTO.getProductId() != null && orderItemDTO.getProductId().intValue() == 1) {
                                if (DataLoadService.shopBranchZiDingYiProductIdMap != null) {
                                    Map<Integer, Integer> branchIdProductIdMap = DataLoadService.shopBranchZiDingYiProductIdMap.get(orderDTO.getShopId());

                                    if (branchIdProductIdMap != null) {
                                        Integer zidingyiProductId = branchIdProductIdMap.get(branchId);

                                        if (zidingyiProductId != null) {
                                            orderItemDTO.setProductId(zidingyiProductId);
                                            if (DataLoadService.productMap != null) {
                                                Product tempProduct = DataLoadService.productMap.get(zidingyiProductId);
                                                if (tempProduct != null) {
                                                    orderItemDTO.setPrice(tempProduct.getPrice());
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    Integer tempBranchId = branchId;
                    ThreadManager.executorService.execute(()->{
                        correctService.correctProductImg(orderDTO, productImgModel, tempBranchId);
                        try {
                            logger.info("===============added=====productImgModel====" + JsonUtil.toJson(productImgModel));
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                    });
                }
            }
        }

        /**
         * 检测是否有会员等级授权问题
         */
        if (isCustomerGroupNotAllow(orderDTO)) {
            throw new ServiceException("会员查询失败");
        }

        Shop shop = null;
        if (DataLoadService.shopMap != null) {
            shop = DataLoadService.shopMap.get(orderDTO.getShopId());
        }
        if (shop == null) {
            shop = shopService.findShopById(orderDTO.getShopId());
        }

        if (shop != null && StringUtils.hasText(shop.getApiServiceClassName())) {
            Object api = SpringUtil.getBean(shop.getApiServiceClassName());
            if (api != null) {
                ShopApiInterface shopApiInterface = (ShopApiInterface)api;
                BaseChargeResp baseChargeResp = shopApiInterface.payPreHandler(orderDTO);

                if (baseChargeResp != null && baseChargeResp.getData() != null) {
                    if (baseChargeResp.getData() instanceof OrderVO) {
                        return (OrderVO)baseChargeResp.getData();
                    }
                }
            }
        }

        //二维码支付订单
        if (orderDTO.getPayType() == PayType.QRCODEPAY) {
            orderDTO.setOrderNo("Q" + orderDTO.getOrderNo());
            return createQrcodeOrder(orderDTO, ip);
        }
        //实体卡订单
        if (orderDTO.getPayType() == PayType.CARDPAY) {
            if (!StringUtils.hasText(orderDTO.getCardNo())){
                throw new ServiceException(WX_PAYCARD_NOT_EXIST);
            }
            orderDTO.setOrderNo("C" + orderDTO.getOrderNo());

            if (shop.getCardPayType() != null && shop.getCardPayType().equals(1) && !shop.getPayType().equals(9)  && !shop.getPayType().equals(21)) {
                return createYPCardOrder(orderDTO, 1);
            }

            if (shop.getCardPayType() != null && shop.getCardPayType() == 2){
                orderDTO.setCardNo(orderDTO.getCardNo().substring(0,8));
                return createYPCardOrder(orderDTO, 1);
            }

            if (shop.getPayType() == 6) {

            }

            if (shop.getPayType() == 17) {

                //读取到的卡位数非10位十进制数时
                if (orderDTO.getCardNo().length() > 10) {
                    String card_id = orderDTO.getCardNo().substring(0, 8);
                    System.out.println(card_id);
                    String card_id_1 = card_id.substring(0, 2);
                    String card_id_2 = card_id.substring(2, 4);
                    String card_id_3 = card_id.substring(4, 6);
                    String card_id_4 = card_id.substring(6, 8);
                    String newCard_id = card_id_4 + card_id_3 + card_id_2 + card_id_1;
                    Long valueTen2 = Long.parseLong(newCard_id, 16);

                    orderDTO.setCardNo(valueTen2.toString());
                }
                BaseChargeResp baseChargeResp = renShouTangService.cardPay(orderDTO);

                if (baseChargeResp != null && baseChargeResp.getCode() == 200) {
                    //支付成功
                    OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                    PayCard payCard = new PayCard();
                    payCard.setAccountbalance((Long)baseChargeResp.getData());
                    orderVO.setPayCard(payCard);
                    return orderVO;
                }else {
                    throw new ServiceException("支付失败");
                }
            }
            if (shop.getPayType() == 8) {

                //从金桥给的卡号支付接口
                logger.info("CARDPAY:从金桥实体卡号支付接口:{}", shop);
                String cardNo = orderDTO.getCardNo();
                int i=0;
                for (Byte s : cardNo.getBytes()) {
                    logger.info("bite=" + s);
                    if (s > 57 || s < 48) {
                        break;
                    }
                    i++;
                }
                cardNo = cardNo.substring(0, i);
                orderDTO.setCardNo(cardNo);
                logger.info("cardNo===" + cardNo);

                if (StringUtils.isEmpty(orderDTO.getCardNo())) {
                    throw new ServiceException(HTTP_MESSAGE_NOT_READABLE);
                }

                logger.info("before checkOrder===" + cardNo);
                logger.info("after checkOrder===" + cardNo);


                String result = JinQiaoPayController.CRMCardPayInterface(
                        orderDTO.getCardNo(),
                        PriceUtil.changeF2Y(orderDTO.getRealFee()),
                        orderDTO.getOrderNo());
                if (result.equals("failed")){
                    throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
                }
            }

            if (shop.getPayType() == 16){
                Condition condition = new Condition(ShopCaogenyaoConfig.class);
                condition.or().andEqualTo("shopId",shop.getId());
                List<ShopCaogenyaoConfig> shopCaogenyaoConfigList = shopCaogenyaoConfigRepository.findByCondition(condition);
                if (null == shopCaogenyaoConfigList || shopCaogenyaoConfigList.size() == 0){
                    throw new ServiceException("店铺信息尚未配置");
                }
                ShopCaogenyaoConfig config = shopCaogenyaoConfigList.get(0);
                JSONObject jsonObject = caoGenYaoPay.caoGenYaoPay(Long.parseLong(orderDTO.getCardNo()),orderDTO.getSerialNumber(),BigDecimal.valueOf(Long.valueOf(orderDTO.getRealFee())).divide(new BigDecimal(100)).doubleValue(),config.getCgyCompanyId().longValue(),config.getCgyShopId(),config.getCgyTerminalId());
                String status = jsonObject.getString("status");
                String successStatus = "1";
                if (!successStatus.equals(status)){
                    throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
                }
                orderDTO.setOrderNo(orderDTO.getOrderNo()+"CGY");
                return this._createOrder(orderDTO, PayStatus.SUCCESS);
            }
            //杭州市民卡
            if(shop.getPayType().equals(9) || shop.getPayType().equals(21)){
                if (orderDTO.getIsSMKOrder() == null){
                    orderDTO.setIsSMKOrder(1);
                }
                if (orderDTO.getIsSMKOrder().equals(1)) {
                    JSONObject personalResult = hzShiMingService.queryIdent(orderDTO.getCardNo());
                    if (null == personalResult) {
                        throw new ServiceException(WX_MICROPAY_ERROR);
                    }
                    String cardType = personalResult.getString("cardkind");
                    String custname = personalResult.getString("custname");
                    String cardnumber = personalResult.getString("cardnumber");
                    String idcard = personalResult.getString("idcard");
                    String csn = personalResult.getString("csn");
                    String phoneNo = personalResult.getString("mobile");
                    Customer customer = customerService.findSMKCustomer(idcard);
                    if (customer == null){
                        customer = new Customer();
                        customer.setShopPaycardid(cardnumber);
                        customer.setIdcardNum(idcard);
                        customer.setName(custname);
                        customer.setPhone(phoneNo);
                        customer.setCustomerType(cardType);
                        customerRepository.save(customer);
                        customerService.createPayCard(customer.getId(), orderDTO.getShopId());
                    }
                    orderDTO.setCustomerId(customer.getId());
                    orderDTO.setCustomerPhone(customer.getPhone());
                    logger.info(idcard);
                    String birthday = idcard.substring(6, 14);
                    logger.info(birthday);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                    Date date = sdf.parse(birthday);
                    Integer age = getAgeByBirth(date);
                    logger.info("" + age);
                    if (orderDTO.getPackageId() != null){
                        ShopPackageDiscount shopPackageDiscount = shopPackageDiscountRepository.findById(orderDTO.getPackageId());
                        orderDTO.setRealFee(shopPackageDiscount.getPrice1());
                        if (age >= 60 && age <= 69) {
                            orderDTO.setRealFee(shopPackageDiscount.getPrice2());
                        } else if (age >= 70 && age <= 79) {
                            orderDTO.setRealFee(shopPackageDiscount.getPrice3());
                        } else if (age >= 80 && age <= 89) {
                            orderDTO.setRealFee(shopPackageDiscount.getPrice4());
                        } else if (age >= 90) {
                            orderDTO.setRealFee(shopPackageDiscount.getPrice5());
                        }
                    }else {
                        Integer type = 1;
                        if (age >= 60 && age <= 69) {
                            type = 2;
                        } else if (age >= 70 && age <= 79) {
                            type = 3;
                        } else if (age >= 80 && age <= 89) {
                            type = 4;
                        } else if (age >= 90) {
                            type = 5;
                        }
                        logger.info("" + type);
                        Condition shiMingKaDiscountCondition = new Condition(ShopShimingkaDiscount.class);
                        shiMingKaDiscountCondition.or().andEqualTo("shopid", shop.getId())
                                .andEqualTo("type", type);
                        ShopShimingkaDiscount shopShimingkaDiscount = shopShimingkaDiscountRepository.findByCondition(shiMingKaDiscountCondition).get(0);
                        Long price = orderDTO.getRealFee() * shopShimingkaDiscount.getDiscount() / 100;
                        if (price == 0) {
                            price = 1L;
                        }
                        orderDTO.setRealFee(price);
                    }
                    orderDTO.setCustomerName(custname);
                    Condition initCondition = new Condition(InitInfo.class);
                    initCondition.or().andEqualTo("cashierdeskid", orderDTO.getCashierDeskId());
                    InitInfo initInfo = initInfoRepository.findByCondition(initCondition).get(0);
                    JSONObject result = SrPayService.getSrPayPrice(initInfo.getDeviceid(), cardnumber, custname, idcard, orderDTO.getOrderNo(), PriceUtil.changeF2Y(orderDTO.getRealFee()), cardType, shop.getShimingkaShopid());
                    if (null == result) {
                        throw new ServiceException(WX_MICROPAY_ERROR);
                    }
                    String srOrder = result.getString("pywddh");
                    //市级消费金额
                    String esjxfje = result.getString("esjxfje");
                    //区级消费金额
                    String eqjxfje = result.getString("eqjxfje");
                    //自费消费金额
                    String ezfxfje = result.getString("ezfxfje");
                    //消费总额
                    String exfze = result.getString("exfze");
                    //优惠金额
                    String eyhzje = result.getString("eyhzje");
                    //将市民卡实付金额存入转存钱包计费字段
                    Integer yktMoney = getPrice(eyhzje);
                    orderDTO.setYktMoney(orderDTO.getRealFee() - yktMoney.longValue());
                    orderDTO.setOrderNo(srOrder);
                    result = SrPayService.getAddress(initInfo.getDeviceid(), srOrder, shop.getShimingkaShopid());
                    if (null == result) {
                        throw new ServiceException(WX_MICROPAY_ERROR);
                    }
                    //交易流水号
                    String plsh = result.getString("plsh");
                    //支付日期
                    String reqTransDate = result.getString("pdate");
                    //支付时间
                    String reqTransTime = result.getString("ptime");
                    //反馈时间
                    String reqTransDateTime = result.getString("pscsj");
                    //JSONObject offlinePayResult = hzShiMingService.offlineConsumer(orderDTO.getCardNo(),srOrder,getPrice(price),initInfo.getDeviceid(),address,shop.getShimingkaShopid(),plsh,reqTransDate,reqTransTime);
                    JSONObject offlinePayResult = hzShiMingService.offlineConsumer(orderDTO.getCardNo(), orderDTO.getOrderNo(), getPrice(esjxfje), getPrice(eqjxfje), getPrice(ezfxfje), getPrice(eyhzje), initInfo.getDeviceid(), shop.getShimingkaShopid(), plsh, reqTransDate, reqTransTime, orderDTO.getPosseq(), orderDTO.getIcdata());
                    System.out.println("------------");
                    System.out.println(cardnumber);
                    System.out.println("------------");
                    System.out.println(csn);
                    System.out.println("------------");
                    orderDTO.setCardNo(cardnumber);
                    if (null == offlinePayResult) {
                        return createYPCardOrder(orderDTO, 0);
                    }
                    String payResult = offlinePayResult.getString("data");
                    String originalSerialNo = offlinePayResult.getString("reqSeq");
                    if (payResult.equals("0")) {
                        return this._createOrder(orderDTO, PayStatus.SUCCESS, originalSerialNo, 0, null, reqTransDateTime);
                    } else if (payResult.equals("3")) {
                        Integer count = 0;
                        while (true) {
                            try {
                                Thread.sleep(2 * 1000); //设置暂停的时间 5 秒
                                count++;
                                logger.info(dbCompareDateFormat.format(new Date()) + "--订单查询支付状态请求第" + count + "次");
                                offlinePayResult = hzShiMingService.queryTransSeq(originalSerialNo, orderDTO.getOrderNo(), shop.getShimingkaShopid());
                                if (null == offlinePayResult) {
                                    continue;
                                }
                                String orderStatus = offlinePayResult.getString("status");
                                if (orderStatus.equals("1")) {
                                    return this._createOrder(orderDTO, PayStatus.SUCCESS, originalSerialNo, 0, null, reqTransDateTime);
                                }
                                if (orderStatus.equals("2")) {

                                    throw new ServiceException(WX_MICROPAY_ERROR);
                                }
                                if (count == 5) {
                                    //撤销订单
                                    ShimingkaOrder shimingkaOrder = new ShimingkaOrder();
                                    shimingkaOrder.setAmount(getPrice(exfze).intValue());
                                    shimingkaOrder.setOrderno(orderDTO.getOrderNo());
                                    shimingkaOrder.setOriginalserialno(originalSerialNo);
                                    shimingkaOrder.setOriginaltransdate(offlinePayResult.getString("reqTransDate"));
                                    shimingkaOrder.setOriginaltranstime(offlinePayResult.getString("reqTransTime"));
                                    shimingkaOrder.setPaystatus(0);
                                    shimingkaOrder.setStatus(3);
                                    shimingkaOrder.setShopId(shop.getId());
                                    shimingkaOrderRepository.save(shimingkaOrder);
                                    logger.info("市民卡支付失败,走云澎支付");
                                    return createYPCardOrder(orderDTO, 0);
                                }
                            } catch (InterruptedException e) {
                                throw new ServiceException(WX_MICROPAY_ERROR);
                            }
                        }

                    } else if (payResult.equals("5")) {
                        logger.info("市民卡支付失败,走云澎支付");
                        return createYPCardOrder(orderDTO, 0);
                    }
                } else {
                    return createYPCardOrder(orderDTO, 5);
                }
            }

            if(shop.getPayType() == 19){
                BaseChargeResp resp = ruiJingService.cardPay(orderDTO);
                if (resp != null){
                    JSONObject result = (JSONObject) resp.getData();
                    JSONObject data = result.getJSONObject("data");
                    orderDTO.setRealFee(data.getLong("amount"));
                    orderDTO.setCustomerName(data.getString("name"));
                    OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                    PayCard payCard = new PayCard();
                    payCard.setAccountbalance(data.getLong("balance"));
                    orderVO.setPayCard(payCard);
                    return orderVO;
                }else {
                    throw new ServiceException(WX_MICROPAY_ERROR);
                }
            }


            if (shop.getPayType() == 12){
                JSONObject customerResult = zhenYuanPay.getaccount(orderDTO.getCardNo(),"");
//                JSONObject customerResult = zhenYuanPay.getaccount("e1e0cf7c000000000000","");
                if (customerResult == null){
                    throw new ServiceException(WX_MICROPAY_ERROR);
                }
                String accNum = customerResult.getString("accNum");
                JSONObject payResult = zhenYuanPay.pay(accNum,PriceUtil.changeF2Y(orderDTO.getRealFee()),orderDTO.getSerialNumber(),"");
                if (payResult == null){
                    throw new ServiceException(WX_MICROPAY_ERROR);
                }
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setCustomerName(payResult.getString("accName"));
                PayCard payCard = new PayCard();
                Long money = getRealMoney(customerResult.getString("balance")) - orderDTO.getRealFee();
                payCard.setAccountbalance(money);
                orderVO.setPayCard(payCard);
                return orderVO;
            }

            OrderVO orderResultVo = createPhysicalCardOrder(orderDTO, shop);


            if (orderResultVo.getPayCard() == null && shop != null && shop.getPayType() != null) {
                orderResultVo.setPayCard(new PayCard());
                if (shop.getPayType() == 8) {
                    JinQiaoPayCardItem jinQiaoPayCardItem = JinQiaoPayController.GetCardInfoByMemInterface(orderDTO.getCardNo());
                    Long balance = jinQiaoPayCardItem.getCurrentMoney();
                    orderResultVo.getPayCard().setAccountbalance(balance);
                }

                /**
                 * 3:自有渠道支付
                 * 5:食云集项目自有支付
                 * 6:乐天商户支付
                 * 7:区政府支付流程
                 * 8:金桥支付
                 */
                if (shop.getPayType() == 7) {
                    try {
                        if (orderDTO.getCustomerId() == null || orderDTO.getCustomerId() == 0){
                            logger.info("none customerId");
                        }else {
//                            String balance = zytkService.GetAccDBMoney(orderDTO.getCardNo(), shop.getId(), ZytkService.cardType);

//                            if (balance != null) {
//                                orderResultVo.getPayCard().setAccountbalance(Long.valueOf(balance));
//                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.info(e.getMessage());
                    }
                }

                if (shop.getPayType() == 6) {
                    try {
                        orderResultVo.getPayCard().setAccountbalance(orderDTO.getAccountBalance() - orderDTO.getRealFee());
                        if (orderResultVo.getPayCard().getAccountbalance() < 0) {
                            orderResultVo.getPayCard().setAccountbalance(0l);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.info(e.getMessage());
                    }
                }
            }
            return orderResultVo;
        }
        //人脸支付
        if (orderDTO.getPayType() == PayType.FACEPAY) {
            long s1 = System.currentTimeMillis();

            logger.info("s1=" + s1);
            long s2 = System.currentTimeMillis();
            logger.info("s2=" + s2);

            orderDTO.setOrderNo("F" + orderDTO.getOrderNo());
            OrderVO orderResultVo = createFaceOrder(orderDTO, ip);
            long s3 = System.currentTimeMillis();
            logger.info("s9=" + s3);
            logger.info("" + (s3 - s1));

            return orderResultVo;
        }
        //扫码支付
        if (orderDTO.getPayType() == PayType.MICROPAY) {

            if (shop == null) {
                throw new ServiceException("商户不存在");
            }

            if (branchId == null) {
                if (DataLoadService.cashierDeskBranchMap != null) {
                    branchId = DataLoadService.cashierDeskBranchMap.get(orderDTO.getCashierDeskId());
                }

                if (branchId == null || branchId == 0) {
                    CashierDesk cashierDesk = cashierDeskMapper.selectByPrimaryKey(orderDTO.getCashierDeskId());
                    if (cashierDesk != null) {
                        branchId = cashierDesk.getBranchid();
                    }

                    if (branchId == null || branchId == 0) {
                        Branch branch = DataLoadService.branchListMap.get(cashierDesk.getShopid());
                        if (branch != null) {
                            branchId = branch.getBranchId();
                        }
                    }
                }
            }

            if (branchId != null && DataLoadService.branchListMap != null) {
                Branch branch = DataLoadService.branchListMap.get(branchId);
                if (branch != null && StringUtils.hasText(branch.getSubAppid())) {
                    shop.setSubAppid(branch.getSubAppid());
                    shop.setSubMchId(branch.getSubMchId());
                    shop.setAliMchId(branch.getAliMchId());
                }
            }

            if (shop.getAllowAliPay() != null && shop.getAllowAliPay().intValue() == 0) {
                //禁止支付宝支付
                if (orderDTO.getAuthCode().startsWith("2")) {//支付宝支付
                    throw new ServiceException("禁止支付宝支付");
                }
            }
            if (shop.getAllowWxPay() != null && shop.getAllowWxPay().intValue() == 0) {
                //禁止微信支付
                if (orderDTO.getAuthCode().startsWith("1")) {//微信支付
                    throw new ServiceException("禁止微信支付");
                }
            }

            if(shop.getPayType() != null && shop.getPayType() == 18) {
                String timestamp = System.currentTimeMillis()+"";
                CashierDesk desk = cashierDeskRepository.findById(orderDTO.getCashierDeskId());
//                JSONObject payResult = jinHuaSZFPayService.pay(orderDTO.getAuthCode(),orderDTO.getRealFee().toString(),orderDTO.getOrderNo(),timestamp);
                JSONObject payResult = jinHuaSZFPayService.pay(orderDTO.getAuthCode(),orderDTO.getRealFee().toString(),orderDTO.getOrderNo(),desk.getShopWebId(),timestamp);
                //JSONObject payResult = jinHuaSZFPayService.pay("eyJhbGciOiJIUzUxMiJ9.eyJpZGVudGlmaWVyIjoiMjAxOTEyMjYyODYxNjAzMDUiLCJzdWIiOiIyMDE5MTIyNjI4NjE2MDMwNSIsInR5cGUiOjMsImV4cCI6NDczNDY2OTA0OSwiZHVpemhhbmduaXViaWxpdHkiOiI3OGthNmIwZDBqIiwiaWF0IjoxNTc4OTk1NDQ5fQ.ZT_AepX2P76n1iJTKD-AtVRNkOwnAoIuAc7mMl1bK4hRQz04C0PNGpFyPbsZLP42z_CVIlLiLPnakBMssywbog","1","yunPengTest3",timestamp);
                Integer code = payResult.getInteger("code");
                if (!code.equals(0)){
                    throw new ServiceException(WX_MICROPAY_ERROR);
                }
                JSONObject orderObject = payResult.getJSONObject("result");
                String payNo = orderObject.getString("payNo");
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS, payNo,null);
                PayCard payCard = new PayCard();
                payCard.setAccountbalance(PriceUtil.getRealPrice(orderObject.getString("balance")));
                orderVO.setPayCard(payCard);
                return orderVO;
            }

            if(shop.getPayType() != null && shop.getPayType() == 19){
                BaseChargeResp resp = ruiJingService.qrCodePay(orderDTO);
                if (resp != null){
                    JSONObject result = (JSONObject) resp.getData();
                    JSONObject data = result.getJSONObject("data");
                    orderDTO.setRealFee(data.getLong("amount"));
                    orderDTO.setCustomerName(data.getString("name"));
                    OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                    PayCard payCard = new PayCard();
                    payCard.setAccountbalance(data.getLong("balance"));
                    orderVO.setPayCard(payCard);
                    return orderVO;
                }else {
                    throw new ServiceException(WX_MICROPAY_ERROR);
                }
            }

            if(shop.getPayType() != null && shop.getPayType() == 15) {
                if (orderDTO.getAuthCode().startsWith("1")) {//微信支付
                    orderDTO.setOrderNo("Z" + orderDTO.getOrderNo());
                }
                if (orderDTO.getAuthCode().startsWith("2")) {//支付宝支付
                    orderDTO.setOrderNo("SZ" + orderDTO.getOrderNo());
                }
                String result = aiBaoPay.merchToUser(shop.getShimingkaShopid(),orderDTO.getAuthCode(),PriceUtil.changeF2Y(orderDTO.getRealFee()),null,null,orderDTO.getOrderNo());
                logger.info(result);
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                return orderVO;
            }
            //正元上外支付
            if(shop.getPayType() != null && shop.getPayType() == 12){
                logger.info(orderDTO.getAuthCode());
                JSONObject result = zhenYuanPay.parseqrcode(orderDTO.getAuthCode(),"");
                String accNum = result.getString("accNum");
                String cardAccNum = result.getString("cardAccNum");
                zhenYuanPay.pay(accNum,PriceUtil.changeF2Y(orderDTO.getRealFee()),orderDTO.getSerialNumber(),"");

                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                return orderVO;
            }
            //传贝支付
            if (shop.getPayType() != null && shop.getPayType() == 10) {
                if (orderDTO.getAuthCode().startsWith("1")) {//微信支付
                    orderDTO.setOrderNo("Z" + orderDTO.getOrderNo());
                }
                if (orderDTO.getAuthCode().startsWith("2")) {//支付宝支付
                    orderDTO.setOrderNo("SZ" + orderDTO.getOrderNo());
                }
                return createChuanBeiPay(orderDTO);
            }


            if (shop.getPayType() != null && shop.getPayType() == 8) {

                if ((orderDTO.getAuthCode().startsWith("1")
                        || orderDTO.getAuthCode().startsWith("2"))

                        && orderDTO.getAuthCode().length() == 18
                ) {//微信、支付宝 支付
                    logger.info("金桥微信或支付宝 支付");

                    if (orderDTO.getAuthCode().startsWith("1")) {//微信支付
                        orderDTO.setOrderNo("Z" + orderDTO.getOrderNo());
//                        return createWxMicroOrderForServerPay(orderDTO, ip, shop);
                        return createAliMicroOrderForServerPay(orderDTO, shop.getSubAppid(), shop.getAliMchId());
                    }


                    if (orderDTO.getAuthCode().startsWith("2")) {//支付宝支付
                        orderDTO.setOrderNo("SZ" + orderDTO.getOrderNo());
                        return createAliMicroOrderForServerPay(orderDTO, shop.getSubAppid(), shop.getAliMchId());
                    }

                } else {
                    logger.info("金桥会员二维码走金桥支付接口");
                    String result = JinQiaoPayController.CRMCardPayInterface(orderDTO.getAuthCode(),
                            PriceUtil.changeF2Y(orderDTO.getRealFee()),orderDTO.getOrderNo());
                    logger.info(result);
                    if (result.equals("failed")){
                        throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
                    }
                    OrderVO orderResultVo = this._createOrder(orderDTO, PayStatus.SUCCESS);

                    if (orderResultVo.getPayCard() == null && shop != null && shop.getPayType() != null) {
                        orderResultVo.setPayCard(new PayCard());
                        JinQiaoPayCardItem jinQiaoPayCardItem = JinQiaoPayController.GetCardInfoByMemInterface(orderDTO.getAuthCode());
                        if (jinQiaoPayCardItem != null) {
                            Long balance = jinQiaoPayCardItem.getCurrentMoney();
                            orderResultVo.getPayCard().setAccountbalance(balance);
                        }
                    } else {
                        Shop tempShop = shop;
                        ThreadManager.executorService.submit(() -> {
                            createYKTCard(tempShop, orderDTO.getCustomerId(), orderDTO.getAuthCode());
                        });
                    }

                    return orderResultVo;
                }
            }
            if (shop.getPayType() != null && shop.getPayType() == 5) {
                return createShiYunJiPay(orderDTO);
            }

            if (shop.getPayType() != null && shop.getPayType() == 3) {
                orderDTO.setOrderNo("S" + orderDTO.getOrderNo());
                return createWxMicroOrderSpecial(orderDTO);
            } else {
                if (shop.getPayType() != null && shop.getPayType() == 4) {//走服务商支付

                    if (orderDTO.getAuthCode().startsWith("1")) {//微信支付
                        orderDTO.setOrderNo("Z" + orderDTO.getOrderNo());
//                        return createWxMicroOrderForServerPay(orderDTO, ip, shop);
                        return createAliMicroOrderForServerPay(orderDTO, shop.getSubAppid(), shop.getAliMchId());
                    }


                    if (orderDTO.getAuthCode().startsWith("2")) {//支付宝支付
                        orderDTO.setOrderNo("SZ" + orderDTO.getOrderNo());
                        return createAliMicroOrderForServerPay(orderDTO, shop.getSubAppid(), shop.getAliMchId());
                    }

                }

                if (orderDTO.getAuthCode().startsWith("9")) {//会员二维码支付
                    orderDTO.setOrderNo("M" + orderDTO.getOrderNo());
                    return createPayCodeOrder(orderDTO);
                }else {
                    if (orderDTO.getAuthCode().startsWith("2")) {//支付宝支付
                        if (StringUtils.hasText(shop.getSubAppid())) {
                            orderDTO.setOrderNo("SZ" + orderDTO.getOrderNo());


                            OrderVO orderVO = createAliMicroOrderForServerPay(orderDTO, shop.getSubAppid(), shop.getAliMchId());

                            //人寿堂支付
                            if (shop.getPayType() == 17) {
                                ThreadManager.executorService.execute(() -> {
                                    renShouTangService.aliPay(orderDTO);
                                });
                            }

                            return orderVO;
                        } else {
                            orderDTO.setOrderNo("SZ" + orderDTO.getOrderNo());
                            OrderVO orderVO = createAliMicroOrder(orderDTO);
                            //人寿堂支付
                            if (shop.getPayType() == 17) {
                                ThreadManager.executorService.execute(() -> {
                                    renShouTangService.aliPay(orderDTO);
                                });
                            }
                            return orderVO;
                        }
                    } else if (orderDTO.getAuthCode().startsWith("1")) {//微信支付

                        if (StringUtils.hasText(shop.getSubAppid())) {
                            orderDTO.setOrderNo("Z" + orderDTO.getOrderNo());
                            OrderVO orderVO = createAliMicroOrderForServerPay(orderDTO, shop.getSubAppid(), shop.getAliMchId());

                            //人寿堂支付
                            if (shop.getPayType() == 17) {
                                ThreadManager.executorService.execute(() -> {
                                    renShouTangService.wxPay(orderDTO);
                                });
                            }

                            return orderVO;
                        } else {
                            orderDTO.setOrderNo("Z" + orderDTO.getOrderNo());
                            OrderVO orderVO = createWxMicroOrder(orderDTO, ip);
                            //人寿堂支付
                            if (shop.getPayType() == 17) {
                                ThreadManager.executorService.execute(() -> {
                                    renShouTangService.wxPay(orderDTO);
                                });
                            }

                            return orderVO;
                        }
                    }else {
                        throw new ServiceException("不支持的二维码类型");
                    }
                }
            }
        }

        //其他支付
        return _createOrder(orderDTO, PayStatus.SUCCESS);

    }


    private OrderVO createWxMicroOrder(OrderDTO orderDTO, String ip) {
        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }
        Boolean isSuccess = wxPayService.micropay(orderDTO.getOrderNo(), orderDTO.getRealFee() + "", ip, orderDTO.getAuthCode());
        if (!isSuccess) throw new ServiceException(WX_MICROPAY_ERROR);
        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
        if (discountOrder != null) {
            orderVO.setNote(discountOrder.getNote());
        }

        return orderVO;
    }

    private OrderVO createYPCardOrder(OrderDTO orderDTO, Integer orderType) {

        PayCard payCard;
        if (orderType == 1 || orderType == 5) {
            payCard = customerService.getYpCard(orderDTO.getCardNo(),orderDTO.getShopId());
        }else{
            payCard = customerService.getCustomerPayCard(orderDTO.getCustomerId(), orderDTO.getShopId());
            if (payCard == null) {
                customerService.createPayCard(orderDTO.getCustomerId(), orderDTO.getShopId());
                throw new ServiceException(WX_MICROPAY_ERROR);
            }
        }

        Integer customerID = payCard.getCustomerid();


        Customer customer = customerRepository.findById(customerID);
        orderDTO.setCustomerId(customerID);
        orderDTO.setCustomerName(customer.getName());
        orderDTO.setCustomerPhone(customer.getPhone());
        orderDTO.setCardNo(payCard.getCardno());
        DiscountOrderDetail discountOrder = null;
        if (orderType.equals(5)) {
            String idCard = customer.getIdcardNum();
            if (idCard == null){
                if (orderDTO.getCustomerGroupID() == null) {
                    Condition condition = new Condition(CustomerExtend.class);
                    condition.or().andEqualTo("shopId", orderDTO.getShopId())
                            .andEqualTo("customerId", payCard.getCustomerid());
                    List<CustomerExtend> customerExtendList = customerExtendMapper.selectByCondition(condition);
                    if (customerExtendList != null && customerExtendList.size() > 0) {
                        CustomerExtend customerExtend = customerExtendList.get(0);
                        if (customerExtend.getIsAudit() == 0) {
                            throw new ServiceException(CUSTOMER_NOT_EXIST);
                        }
                        orderDTO.setCustomerGroupID(customerExtend.getGroupId());
                    }
                }

                if (isCustomerGroupNotAllow(orderDTO)) {
                    throw new ServiceException(CUSTOMER_NOT_EXIST);
                }

                Integer shopId = orderDTO.getShopId();
                if (shopId.equals(wuJinShopId)) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = new Date();
                    Integer count = discountOrderMapper.findDisCountOrderCount(orderDTO.getCustomerId(), orderDTO.getShopId(), sdf.format(date) + " 00:00:00", sdf.format(date) + " 23:59:59");
                    if (count < 1) {
                        discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
                    }
                } else {
                    discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
                }

                if (discountOrder != null) {
                    orderDTO.setRealFee(discountOrder.getTotalFee());

                    if (discountOrder.getTotalFee() == 0) {
                        checkConsumeCount(orderDTO, customerID);
                        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                        orderVO.setNote(discountOrder.getNote());
                        return orderVO;
                    }
                }
            }else {
                String birthday = idCard.substring(6, 14);
                logger.info(birthday);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                Date date;
                Integer age = null;
                try {
                    date = sdf.parse(birthday);
                    age = getAgeByBirth(date);
                } catch (ParseException e) {

                }
                logger.info("" + age);
                Integer type = 1;
                if (age >= 60 && age <= 69) {
                    type = 2;
                } else if (age >= 70 && age <= 79) {
                    type = 3;
                } else if (age >= 80 && age <= 89) {
                    type = 4;
                } else if (age >= 90) {
                    type = 5;
                }
                logger.info("" + type);
                Condition shiMingKaDiscountCondition = new Condition(ShopShimingkaDiscount.class);
                shiMingKaDiscountCondition.or().andEqualTo("shopid", orderDTO.getShopId())
                        .andEqualTo("type", type);
                ShopShimingkaDiscount shopShimingkaDiscount = shopShimingkaDiscountRepository.findByCondition(shiMingKaDiscountCondition).get(0);
                Long price = orderDTO.getRealFee() * shopShimingkaDiscount.getDiscount() / 100;
                if (price == 0) {
                    price = 1L;
                }
                orderDTO.setRealFee(price);
            }
        } else if (orderType.equals(1)) {
            if (orderDTO.getCustomerGroupID() == null) {
                Condition condition = new Condition(CustomerExtend.class);
                condition.or().andEqualTo("shopId", orderDTO.getShopId())
                        .andEqualTo("customerId", payCard.getCustomerid());
                List<CustomerExtend> customerExtendList = customerExtendMapper.selectByCondition(condition);
                if (customerExtendList != null && customerExtendList.size() > 0) {
                    CustomerExtend customerExtend = customerExtendList.get(0);
                    if (customerExtend.getIsAudit() == 0) {
                        throw new ServiceException(CUSTOMER_NOT_EXIST);
                    }
                    orderDTO.setCustomerGroupID(customerExtend.getGroupId());
                }
            }

            if (isCustomerGroupNotAllow(orderDTO)) {
                throw new ServiceException(CUSTOMER_NOT_EXIST);
            }

            Integer shopId = orderDTO.getShopId();
            if (shopId.equals(wuJinShopId)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date date = new Date();
                Integer count = discountOrderMapper.findDisCountOrderCount(orderDTO.getCustomerId(), orderDTO.getShopId(), sdf.format(date) + " 00:00:00", sdf.format(date) + " 23:59:59");
                if (count < 1) {
                    discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
                }
            } else {
                discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
            }

            if (discountOrder != null) {
                orderDTO.setRealFee(discountOrder.getTotalFee());

                if (discountOrder.getTotalFee() == 0) {
                    checkConsumeCount(orderDTO, customerID);
                    OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                    orderVO.setNote(discountOrder.getNote());
                    return orderVO;
                }
            }
        }



        Long realFee = orderDTO.getRealFee();

        Long balance = payCard.getAccountbalance();
        Long wxBalance = payCard.getWxAccountbalance();
        Long yktBalance = payCard.getYktAccountbalance();
        Long bzBalance = payCard.getBzAccountbalance();

        Long bzNewBalance = bzBalance - realFee;
        Long yktNewBalance = yktBalance - realFee+ bzBalance;
        Long newBalance = balance - realFee + yktBalance + bzBalance;
        Long wxNewBalance = wxBalance - realFee + balance + yktBalance + bzBalance;

        orderDTO.setMoney(0L);
        orderDTO.setBzMoney(0L);
        orderDTO.setWxMoney(0L);
        orderDTO.setYktMoney(0L);

        if (bzNewBalance >= 0) {
            checkConsumeCount(orderDTO, customerID);
            payCard.setBzAccountbalance(bzNewBalance);
            orderDTO.setBzMoney(realFee);
            payCardRepository.update(payCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, payCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        }else if (yktNewBalance >= 0) {
            checkConsumeCount(orderDTO, customerID);
            payCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(yktNewBalance);
            orderDTO.setYktMoney(realFee - bzBalance);
            payCardRepository.update(payCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, payCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;

        }else if (newBalance >= 0) {
            checkConsumeCount(orderDTO, customerID);
            payCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(0L);
            orderDTO.setYktMoney(yktBalance);
            payCard.setAccountbalance(newBalance);
            orderDTO.setMoney(realFee - bzBalance - yktBalance);
            payCardRepository.update(payCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, payCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        } else if (wxNewBalance >= 0) {
            checkConsumeCount(orderDTO, customerID);
            payCard.setYktAccountbalance(0L);
            orderDTO.setYktMoney(yktBalance);
            payCard.setAccountbalance(0L);
            orderDTO.setMoney(balance);
            payCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            payCard.setWxAccountbalance(wxNewBalance);
            orderDTO.setWxMoney(realFee - bzBalance - yktBalance - balance);
            payCardRepository.update(payCard);
            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS, null, payCard.getId());

            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        } else {
            throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
        }
    }

    private OrderVO createPayCodeOrder(OrderDTO orderDTO) {

        PayCard payCard = _getPayCardByPayCode(orderDTO.getAuthCode());
        Integer customerID = payCard.getCustomerid();
        Customer customer = customerRepository.findById(customerID);
        orderDTO.setCustomerId(customerID);
        orderDTO.setCustomerName(customer.getName());
        orderDTO.setCustomerPhone(customer.getPhone());
        orderDTO.setCardNo(payCard.getCardno());

        checkConsumeCount(orderDTO, orderDTO.getCustomerId());

        if (orderDTO.getCustomerGroupID() == null) {
            Condition condition = new Condition(CustomerExtend.class);
            condition.or().andEqualTo("shopId", orderDTO.getShopId())
                    .andEqualTo("customerId", payCard.getCustomerid());
            List<CustomerExtend> customerExtendList = customerExtendMapper.selectByCondition(condition);
            if (customerExtendList != null && customerExtendList.size() > 0) {
                CustomerExtend customerExtend = customerExtendList.get(0);
                if (customerExtend.getIsAudit() == 0){
                    throw new ServiceException(CUSTOMER_NOT_EXIST);
                }
                orderDTO.setCustomerGroupID(customerExtend.getGroupId());
            }
        }

        if (payCard == null) {
            throw new ServiceException(PAYCARD_PAYCODE_INVALID);
        }

        if (payCard.getCardtype().intValue() != 0) {
            throw new ServiceException(PAYCARD_PAYCODE_NOT_SUPPORT);
        }

        if (!payCard.getShopid().equals(orderDTO.getShopId())) {
            throw new ServiceException(PAYCARD_PAYCODE_NOT_SUPPORT);
        }

        Date payCodeDate = payCard.getPayCodeTime();

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -1);

        if (calendar.getTime().after(payCodeDate)) {
            throw new ServiceException(PAYCARD_PAYCODE_INVALID);
        }

        Integer shopId = orderDTO.getShopId();
        DiscountOrderDetail discountOrder = null;
        if(shopId.equals(wuJinShopId)){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = new Date();
            Integer count = discountOrderMapper.findDisCountOrderCount(orderDTO.getCustomerId(),orderDTO.getShopId(),sdf.format(date)+" 00:00:00",sdf.format(date)+" 23:59:59");
            if (count < 1){
                discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
            }
        }else {
            discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
        }

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }

        Long realFee = orderDTO.getRealFee();

        Long balance = payCard.getAccountbalance();
        Long wxBalance = payCard.getWxAccountbalance();
        Long yktBalance = payCard.getYktAccountbalance();
        Long bzBalance = payCard.getBzAccountbalance();

        Long bzNewBalance = bzBalance - realFee;
        Long yktNewBalance = yktBalance - realFee+ bzBalance;
        Long newBalance = balance - realFee + yktBalance + bzBalance;
        Long wxNewBalance = wxBalance - realFee + balance + yktBalance + bzBalance;

        orderDTO.setMoney(0L);
        orderDTO.setBzMoney(0L);
        orderDTO.setWxMoney(0L);
        orderDTO.setYktMoney(0L);

        if (bzNewBalance >= 0){
            payCard.setBzAccountbalance(bzNewBalance);
            orderDTO.setBzMoney(realFee);
            payCardRepository.update(payCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, payCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        }else if (yktNewBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(yktNewBalance);
            orderDTO.setYktMoney(realFee - bzBalance);
            payCardRepository.update(payCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, payCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;

        }else if (newBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(0L);
            orderDTO.setYktMoney(yktBalance);
            payCard.setAccountbalance(newBalance);
            orderDTO.setMoney(realFee - bzBalance - yktBalance);
            payCardRepository.update(payCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, payCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        } else if (wxNewBalance >= 0) {
            payCard.setYktAccountbalance(0L);
            orderDTO.setYktMoney(yktBalance);
            payCard.setAccountbalance(0L);
            orderDTO.setMoney(balance);
            payCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            payCard.setWxAccountbalance(wxNewBalance);
            orderDTO.setWxMoney(realFee - bzBalance - yktBalance - balance);
            payCardRepository.update(payCard);
            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS, null, payCard.getId());

            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        } else {
            throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
        }
    }

    /**
     * 服务商支付
     * @param orderDTO
     * @param ip
     * @return
     */
    private OrderVO createWxMicroOrderForServerPay(OrderDTO orderDTO, String ip, Shop shop) {
        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }
//        Shop shop = shopService.findShopById(orderDTO.getShopId());

        Boolean isSuccess = wxServerPayService.micropayCustomer(orderDTO.getOrderNo(), orderDTO.getRealFee() + "",
                ip, orderDTO.getAuthCode(), null, shop.getSubMchId());
//                ip, orderDTO.getAuthCode(), shop.getSubAppid(), shop.getSubMchId());
        if (!isSuccess) throw new ServiceException(WX_MICROPAY_ERROR);
        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);

        if (discountOrder != null) {
            orderVO.setNote(discountOrder.getNote());
        }
        return orderVO;
    }

    /**
     * 支付宝或微信 服务商B扫C支付
     * @param orderDTO
     * @return
     */
    private OrderVO createAliMicroOrderForServerPay(OrderDTO orderDTO, String subMchId, String shopAliKey) {
        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }

        YilingPayResult isSuccess = aliServerPayService.doPay(orderDTO.getOrderNo(), PriceUtil.changeF2Y(orderDTO.getRealFee()),
                orderDTO.getAuthCode(), null, subMchId, shopAliKey);
        if (!isSuccess.isResult()) throw new ServiceException(WX_MICROPAY_ERROR);


        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS, null, null, isSuccess.getTraceNum(),null);

        if (discountOrder != null) {
            orderVO.setNote(discountOrder.getNote());
        }
        return orderVO;
    }

    /**
     * 山东高速 商户支付
     * @param orderDTO
     * @return
     */
    private OrderVO createWxMicroOrderSpecial(OrderDTO orderDTO) {
        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }

        CashierDesk cashierDesk = cashierDeskRepository.findById(orderDTO.getCashierDeskId());

        Map<String, String> result = wxServerPayService.wuzhenpay20(orderDTO.getAuthCode(),
                orderDTO.getRealFee(), cashierDesk.getCcode());

        boolean isSuccess = "true".equals(result.get("success"));
        if (!isSuccess) throw new ServiceException(WX_MICROPAY_ERROR);
        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS, result.get("payNo"), null);

        if (discountOrder != null) {
            orderVO.setNote(discountOrder.getNote());
        }

        return orderVO;
    }

    private OrderVO createAliMicroOrder(OrderDTO orderDTO) {
        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }
        Boolean isSuccess = AliPayService.barCodePay(orderDTO.getOrderNo(), orderDTO.getAuthCode(), orderDTO.getRealFee(), orderDTO.getOrderNo());
        if (!isSuccess) throw new ServiceException(ALI_MICROPAY_ERROR);
        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);

        if (discountOrder != null) {
            orderVO.setNote(discountOrder.getNote());
        }
        return orderVO;
    }

    public void createMenjinOrder(String authcode, String machineCode) {

        Condition condition = new Condition(CashierDesk.class);
        condition.or().andEqualTo("ccode", machineCode);
        List<CashierDesk> cashierDeskList = cashierDeskRepository.findByCondition(condition);
        if (null == cashierDeskList || cashierDeskList.size() == 0) {
            Condition menJinCondition = new Condition(MenjinBinding.class);
            menJinCondition.or().andEqualTo("ccode",machineCode);
            List<MenjinBinding> menjinBindingList = menjinBindingRepository.findByCondition(menJinCondition);
            if (null == menjinBindingList || menjinBindingList.size() == 0){
                MenjinBinding menjinBinding = new MenjinBinding();
                menjinBinding.setCcode(machineCode);
                menjinBinding.setCreatetime(new Date());
//                menjinBinding.setStatus(0);
                menjinBindingRepository.save(menjinBinding);
            }
            throw new ServiceException(MACHINE_ERROR);
        }
        CashierDesk cashierDesk = cashierDeskList.get(0);
        Integer shopID = cashierDesk.getShopid();
        PayCard payCard;

        if (authcode.length() == 18) {
            payCard = _getPayCardByPayCode(authcode);

            if (!payCard.getShopid().equals(shopID)){
                throw new ServiceException(PAYCARD_PAYCODE_NOT_SUPPORT);
            }
            if (payCard == null) {
                throw new ServiceException(PAYCARD_PAYCODE_INVALID);
            }

            if (payCard.getCardtype().intValue() != 0) {
                throw new ServiceException(PAYCARD_PAYCODE_NOT_SUPPORT);
            }
            Calendar calendar=Calendar.getInstance();
            calendar.add(Calendar.MINUTE,-1);
            Date date=calendar.getTime();
            if (date.after(payCard.getPayCodeTime())){
                throw new ServiceException(PAYCARD_PAYCODE_NOT_SUPPORT);
            }
        }else {
            Condition ypCondition = new Condition(YpCard.class);
            ypCondition.or().andEqualTo("cardMenjinId",authcode)
                    .andEqualTo("shopId",shopID);
            List<YpCard> ypCardList = ypCardRepository.findByCondition(ypCondition);
            if (null == ypCardList || ypCardList.size() == 0){
                throw new ServiceException(CUSTOMER_NOT_EXIST);
            }
            YpCard ypCard = ypCardList.get(0);
            Condition payCardCondition = new Condition(PayCard.class);
            payCardCondition.or().andEqualTo("cardno",ypCard.getCardNo())
                    .andEqualTo("shopid",shopID);
            List<PayCard> payCardList = payCardRepository.findByCondition(payCardCondition);
            if (null == payCardList || payCardList.size() == 0) {
                throw new ServiceException(CUSTOMER_NOT_EXIST);
            }
            payCard = payCardList.get(0);
        }
        CustomerExtend customerExtend = customerService.getCustomerExtend(payCard.getCustomerid(),payCard.getShopid());
        Condition groupCondition = new Condition(CustomerGroupCashierDesk.class);
        groupCondition.or().andEqualTo("cashierDeskId",cashierDesk.getId());
        List<CustomerGroupCashierDesk> customerGroupCashierDesks = customerGroupCashierDeskRepository.findByCondition(groupCondition);
        Boolean isAllow = false;
        if (customerGroupCashierDesks != null && customerGroupCashierDesks.size()>0){
            for (CustomerGroupCashierDesk customerGroupCashierDesk : customerGroupCashierDesks){
                if (customerGroupCashierDesk.getCustomerGroupId().equals(customerExtend.getGroupId())){
                    isAllow = true;
                    break;
                }
            }
            if (!isAllow){
                throw new ServiceException(CUSTOMER_NOT_EXIST);
            }
        }

        ShopMenjinOrder shopMenjinOrder = new ShopMenjinOrder();
        shopMenjinOrder.setShopid(shopID);
        shopMenjinOrder.setCustomerid(payCard.getCustomerid());
        shopMenjinOrder.setDate(new Date());
        shopMenjinOrderRepository.save(shopMenjinOrder);
    }


    public OrderVO createFaceOrder(OrderDTO orderDTO, String ip) {
        checkConsumeCount(orderDTO, orderDTO.getCustomerId());

        long s11 = System.currentTimeMillis();
        logger.info("s11=" + s11);

        PayCard virtualPayCard = null;

        Integer shopId = orderDTO.getShopId();


        if (orderDTO.getCustomerGroupID() == null || orderDTO.getCustomerGroupID() == 0) {
            Condition condition = new Condition(CustomerExtend.class);
            condition.or().andEqualTo("shopId", orderDTO.getShopId())
                    .andEqualTo("customerId", orderDTO.getCustomerId());
            List<CustomerExtend> customerExtendList = customerExtendMapper.selectByCondition(condition);
            if (customerExtendList != null && customerExtendList.size() > 0) {
                CustomerExtend customerExtend = customerExtendList.get(0);
                if (customerExtend.getIsAudit() == 0){
                    throw new ServiceException(CUSTOMER_NOT_EXIST);
                }
                orderDTO.setCustomerGroupID(customerExtend.getGroupId());
            }
        }

        DiscountOrderDetail discountOrder = null;
        if(shopId.equals(wuJinShopId)){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = new Date();
            Integer count = discountOrderMapper.findDisCountOrderCount(orderDTO.getCustomerId(),orderDTO.getShopId(),sdf.format(date)+" 00:00:00",sdf.format(date)+" 23:59:59");
            if (count < 1){
                discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
            }
        }else {
            discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());
        }

        long s12 = System.currentTimeMillis();
        logger.info("s12=" + s12);

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }


        Shop shop = shopService.findShopById(orderDTO.getShopId());

        List<PayCard> payCardList = _getPayCardList(orderDTO.getShopId(), orderDTO.getCustomerId());
        logger.info("shopId=" + shop.getId());

        Customer customer = customerRepository.findById(orderDTO.getCustomerId());

        if (customer != null) {
            orderDTO.setCustomerPhone(customer.getPhone());
        }

        long s13 = System.currentTimeMillis();
        logger.info("s13=" + s13);
        //乐天商户:前端扣款
        if (shop.getPayType() == 6) {
            return this._createOrder(orderDTO, PayStatus.SUCCESS);
        }
        //正元商户
        if (shop.getPayType() == 7) {
            String cardNo = null;
            PayCard yktPayCard = null;
            if (payCardList != null && payCardList.size() > 0) {
                for (PayCard temp : payCardList) {
                    if (CardType.YKT_CARD.getCode().byteValue() == temp.getCardtype()) {
                        cardNo = temp.getCardno();
                        yktPayCard = temp;
                    } else if (CardType.BINGUO_CARD.getCode().byteValue() == temp.getCardtype()) {
                        virtualPayCard = temp;
                    }
                }
            }
            if (yktPayCard != null) {
                long s14 = System.currentTimeMillis();
                logger.info("s14=" + s14);

                ShopZyOrder shopZyOrder = new ShopZyOrder();
                shopZyOrder.setCardId(yktPayCard.getCardno());
                shopZyOrder.setPrice(orderDTO.getRealFee());
                shopZyOrder.setCreateTime(new Date());
                shopZyOrder.setShopId(orderDTO.getShopId());
                shopZyOrder.setSyncStatus(0);
                shopZyOrder.setOrderNo(orderDTO.getOrderNo());
                if (DataLoadService.cashierDeskStatnumMap != null) {
                    shopZyOrder.setStatnum(DataLoadService.cashierDeskStatnumMap.get(orderDTO.getCashierDeskId()));
                }
                shopZyOrderRepository.save(shopZyOrder);

                //从区政府给的卡号支付接口
//                String result = zytkService.PaymentA(yktPayCard.getCardno(), orderDTO.getRealFee().toString(), orderDTO.getShopId());

                long s15 = System.currentTimeMillis();
                logger.info("s15=" + s15);

//                String balance = zytkService.GetAccDBMoney(orderDTO.getCardNo(), orderDTO.getShopId(), null);

                long s16 = System.currentTimeMillis();
                logger.info("s16=" + s16);

                yktPayCard.setYktAccountbalance(yktPayCard.getYktAccountbalance() - orderDTO.getRealFee());
                payCardRepository.update(yktPayCard);

                return this._createOrder(orderDTO, PayStatus.SUCCESS, null, yktPayCard.getId());

            }
        }

        //金桥
        if (shop.getPayType() == 8) {
            String cardNo = null;
            PayCard yktPayCard = null;
            if (payCardList != null && payCardList.size() > 0) {
                for (PayCard temp : payCardList) {
                    if (CardType.YKT_CARD.getCode().byteValue() == temp.getCardtype()) {
                        yktPayCard = temp;
                        cardNo = temp.getCardno();
                    } else if (CardType.BINGUO_CARD.getCode().byteValue() == temp.getCardtype()) {
                        virtualPayCard = temp;
                    }
                }
            }
            if (cardNo != null) {
                //从金桥给的卡号支付接口
                logger.info("走金桥支付接口");
                String result = JinQiaoPayController.CRMCardPayInterface(cardNo,
                        PriceUtil.changeF2Y(orderDTO.getRealFee()),orderDTO.getOrderNo());
                logger.info(result);
                if (result.equals("failed")) {//金桥扣失败后，扣正常人脸虚拟卡账户
//                    throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
                } else {
                    JinQiaoPayCardItem jinQiaoPayCardItem = JinQiaoPayController.GetCardInfoByMemInterface(orderDTO.getCardNo());

                    Long balance = jinQiaoPayCardItem.getCurrentMoney();

                    yktPayCard.setYktAccountbalance(balance);
                    payCardRepository.update(yktPayCard);
                    logger.info("走金桥支付接口end");
                    return this._createOrder(orderDTO, PayStatus.SUCCESS, null, yktPayCard.getId());
                }

                return this._createOrder(orderDTO, PayStatus.SUCCESS);
            }
        }
        //市民卡
        if(shop.getPayType() == 9){
            Condition initCondition = new Condition(InitInfo.class);
            initCondition.or().andEqualTo("cashierdeskid",orderDTO.getCashierDeskId());
            InitInfo initInfo = initInfoRepository.findByCondition(initCondition).get(0);
            logger.info(customer.getName());
            logger.info(customer.getIdcardNum());
            logger.info(customer.getCustomerType());
            orderDTO.setCustomerPhone(customer.getPhone());
            String idcard = customer.getIdcardNum();
            logger.info(idcard);
            String birthday = idcard.substring(6, 14);
            logger.info(birthday);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            Date date = null;
            try {
                date = sdf.parse(birthday);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Integer age = null;
            try {
                age = getAgeByBirth(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            logger.info("age=" + age);
            if (orderDTO.getPackageId() != null){
                ShopPackageDiscount shopPackageDiscount = shopPackageDiscountRepository.findById(orderDTO.getPackageId());
                orderDTO.setRealFee(shopPackageDiscount.getPrice1());
                if (age >= 60 && age <= 69) {
                    orderDTO.setRealFee(shopPackageDiscount.getPrice2());
                } else if (age >= 70 && age <= 79) {
                    orderDTO.setRealFee(shopPackageDiscount.getPrice3());
                } else if (age >= 80 && age <= 89) {
                    orderDTO.setRealFee(shopPackageDiscount.getPrice4());
                } else if (age >= 90) {
                    orderDTO.setRealFee(shopPackageDiscount.getPrice5());
                }
            }else {
                Integer type = 1;
                if (age >= 60 && age <= 69) {
                    type = 2;
                } else if (age >= 70 && age <= 79) {
                    type = 3;
                } else if (age >= 80 && age <= 89) {
                    type = 4;
                } else if (age >= 90) {
                    type = 5;
                }
                logger.info("type=" + type);
                Condition shiMingKaDiscountCondition = new Condition(ShopShimingkaDiscount.class);
                shiMingKaDiscountCondition.or().andEqualTo("shopid", shop.getId())
                        .andEqualTo("type", type);
                ShopShimingkaDiscount shopShimingkaDiscount = shopShimingkaDiscountRepository.findByCondition(shiMingKaDiscountCondition).get(0);
                Long price = orderDTO.getRealFee() * shopShimingkaDiscount.getDiscount() / 100;
                if (price == 0) {
                    price = 1L;
                }
                orderDTO.setRealFee(price);
            }
            JSONObject result = SrPayService.getSrPayPrice(initInfo.getDeviceid(),orderDTO.getCardNo(),customer.getName(),customer.getIdcardNum(),orderDTO.getOrderNo(),PriceUtil.changeF2Y(orderDTO.getRealFee()),customer.getCustomerType(),shop.getShimingkaShopid());
            if (null == result){
                throw new ServiceException(WX_MICROPAY_ERROR);
            }
            logger.info(result.toJSONString());
            String srOrder = result.getString("pywddh");
            //市级消费金额
            String esjxfje = result.getString("esjxfje");
            //区级消费金额
            String eqjxfje = result.getString("eqjxfje");
            //自费消费金额
            String ezfxfje = result.getString("ezfxfje");
            //消费总额
            String exfze = result.getString("exfze");
            //优惠总金额
            String eyhzje = result.getString("eyhzje");
            //将市民卡实付金额存入转存钱包计费字段
            Integer yktMoney = getPrice(eyhzje);
            orderDTO.setYktMoney(orderDTO.getRealFee() - yktMoney.longValue());
            orderDTO.setOrderNo(srOrder);
            result = SrPayService.getAddress(initInfo.getDeviceid(),srOrder,shop.getShimingkaShopid());
            if (null == result){
                throw new ServiceException(WX_MICROPAY_ERROR);
            }
            String plsh = result.getString("plsh");
            String reqTransDate = result.getString("pdate");
            String reqTransTime = result.getString("ptime");
            String reqTransDateTime = result.getString("pscsj");
            if (customer.getImageToken() != null){
                //JSONObject facePayResult = hzShiMingService.faceConsumer(customer,getPrice(price),0,srOrder,initInfo.getDeviceid(),address,shop.getShimingkaShopid(),plsh,reqTransDate,reqTransTime);
                JSONObject facePayResult = hzShiMingService.faceConsumer(customer, getPrice(esjxfje), getPrice(eqjxfje), getPrice(ezfxfje), getPrice(eyhzje), srOrder, initInfo.getDeviceid(), shop.getShimingkaShopid(), plsh, reqTransDate, reqTransTime);
                if (null == facePayResult){
                    logger.info("市民卡支付失败,走云澎支付");
                    return createYPCardOrder(orderDTO, 0);
                }
                String payResult = facePayResult.getString("data");
                if (payResult.equals("-1")){
                    logger.info("市民卡支付失败,走云澎支付");
                    return createYPCardOrder(orderDTO, 0);
                }
                String originalSerialNo = facePayResult.getString("reqSeq");
                customer.setImageToken(null);
                customerRepository.update(customer);
                if (payResult.equals("0")){
                    logger.info("支付成功");
                    return this._createOrder(orderDTO, PayStatus.SUCCESS,originalSerialNo,0,null,reqTransDateTime);
                }else if (payResult.equals("3")){
                    Integer count = 0;
                    while(true) {
                        try {
                            Thread.sleep(2 * 1000); //设置暂停的时间 5 秒
                            count ++ ;
                            logger.info(dbCompareDateFormat.format(new Date()) + "--订单查询支付状态请求第" + count + "次");
                            facePayResult = hzShiMingService.queryTransSeq(originalSerialNo,orderDTO.getOrderNo(),shop.getShimingkaShopid());
                            String orderStatus = facePayResult.getString("status");
                            if (orderStatus.equals("1")){
                                logger.info("支付成功");
                                return this._createOrder(orderDTO, PayStatus.SUCCESS,originalSerialNo,0,null,reqTransDateTime);
                            }
                            if (orderStatus.equals("2")){
                                logger.info("支付失败");
                                throw new ServiceException(WX_MICROPAY_ERROR);
                            }
                            if (count == 5) {
                                //支付超时
                                ShimingkaOrder shimingkaOrder = new ShimingkaOrder();
                                shimingkaOrder.setAmount(getPrice(exfze).intValue());
                                shimingkaOrder.setOrderno(orderDTO.getOrderNo());
                                shimingkaOrder.setOriginalserialno(originalSerialNo);
                                shimingkaOrder.setOriginaltransdate(facePayResult.getString("reqTransDate"));
                                shimingkaOrder.setOriginaltranstime(facePayResult.getString("reqTransTime"));
                                shimingkaOrder.setPaystatus(0);
                                shimingkaOrder.setStatus(3);
                                shimingkaOrder.setShopId(shop.getId());
                                shimingkaOrderRepository.save(shimingkaOrder);
                                logger.info("市民卡支付失败,走云澎支付");
                                return createYPCardOrder(orderDTO, 0);
                            }
                        } catch (InterruptedException e) {
                            throw new ServiceException(WX_MICROPAY_ERROR);
                        }
                    }

                }else if (payResult.equals("5")){
                    logger.info("市民卡支付失败,走云澎支付");
                    return createYPCardOrder(orderDTO, 0);
                }
            }
        }

        if(shop.getPayType() == 13){
            PayCard dikeCard = null;
            Condition payCardCondition = new Condition(PayCard.class);
            payCardCondition.or().andEqualTo("shopid",shop.getId())
                    .andEqualTo("customerid",customer.getId());
            dikeCard = payCardRepository.findByCondition(payCardCondition).get(0);
            if (diKeYWPay.faceConsume("192.168.16.172","3C-97-0E-42-3F-06",dikeCard.getCardno(),customer.getName(),orderDTO.getSerialNumber(),orderDTO.getRealFee().toString())){
                return this._createOrder(orderDTO, PayStatus.SUCCESS);
            }else {
                throw new ServiceException(WX_MICROPAY_ERROR);
            }
        }

        //人寿堂支付
        if (shop.getPayType() == 17) {
            if (payCardList != null && payCardList.size() > 0) {
                virtualPayCard = payCardList.get(0);
                orderDTO.setCardNo(virtualPayCard.getCardno());
                BaseChargeResp baseChargeResp = renShouTangService.cardPay(orderDTO);
                if (baseChargeResp != null && baseChargeResp.getCode() == 0) {
                    //支付成功
                    OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                    PayCard payCard = new PayCard();
                    payCard.setAccountbalance((Long)baseChargeResp.getData());
                    orderVO.setPayCard(payCard);
                    return orderVO;
                }
            }

            throw new ServiceException("支付失败");
        }

        //草根谣支付
        if (shop.getPayType() == 16){
            if (payCardList != null && payCardList.size() > 0) {
                for (PayCard temp : payCardList) {
                    if (CardType.BINGUO_CARD.getCode().byteValue() == temp.getCardtype()) {
                        virtualPayCard = temp;
                    }
                }
            }
            Condition condition = new Condition(ShopCaogenyaoConfig.class);
            condition.or().andEqualTo("shopId",shop.getId());
            List<ShopCaogenyaoConfig> shopCaogenyaoConfigList = shopCaogenyaoConfigRepository.findByCondition(condition);
            if (null == shopCaogenyaoConfigList || shopCaogenyaoConfigList.size() == 0){
                throw new ServiceException("店铺信息尚未配置");
            }
            ShopCaogenyaoConfig config = shopCaogenyaoConfigList.get(0);
            JSONObject jsonObject = caoGenYaoPay.caoGenYaoPay(Long.parseLong(virtualPayCard.getCardno()),orderDTO.getSerialNumber(),BigDecimal.valueOf(Long.valueOf(orderDTO.getRealFee())).divide(new BigDecimal(100)).doubleValue(),config.getCgyCompanyId().longValue(),config.getCgyShopId(),config.getCgyTerminalId());
            String status = jsonObject.getString("status");
            String successStatus = "1";
            if (!successStatus.equals(status)){
                throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
            }
            orderDTO.setOrderNo(orderDTO.getOrderNo()+"CGY");
            return this._createOrder(orderDTO, PayStatus.SUCCESS);
        }

        if (shop.getPayType() == 19){
            BaseChargeResp resp = ruiJingService.facePay(orderDTO);
            if (resp != null){
                JSONObject result = (JSONObject) resp.getData();
                JSONObject data = result.getJSONObject("data");
                orderDTO.setRealFee(data.getLong("amount"));
                orderDTO.setCustomerName(data.getString("name"));
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                PayCard payCard = new PayCard();
                payCard.setAccountbalance(data.getLong("balance"));
                orderVO.setPayCard(payCard);
                return orderVO;
            }else {
                throw new ServiceException(WX_MICROPAY_ERROR);
            }
        }



        if (virtualPayCard == null) {
            if (payCardList != null && payCardList.size() > 0) {
                for (PayCard temp : payCardList) {
                    if (CardType.BINGUO_CARD.getCode().byteValue() == temp.getCardtype()) {
                        virtualPayCard = temp;
                        break;
                    }
                }
            }
        }

        Long realFee = orderDTO.getRealFee();

        orderDTO.setCardNo(virtualPayCard.getCardno());

        Long balance = virtualPayCard.getAccountbalance();
        Long wxBalance = virtualPayCard.getWxAccountbalance();
        Long yktBalance = virtualPayCard.getYktAccountbalance();
        Long bzBalance = virtualPayCard.getBzAccountbalance();

        Long bzNewBalance = bzBalance - realFee;
        Long yktNewBalance = yktBalance - realFee+ bzBalance;
        Long newBalance = balance - realFee + yktBalance + bzBalance;
        Long wxNewBalance = wxBalance - realFee + balance + yktBalance + bzBalance;

        orderDTO.setMoney(0L);
        orderDTO.setBzMoney(0L);
        orderDTO.setWxMoney(0L);
        orderDTO.setYktMoney(0L);

        if (bzNewBalance >= 0){
            virtualPayCard.setBzAccountbalance(bzNewBalance);
            orderDTO.setBzMoney(realFee);
            payCardRepository.update(virtualPayCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, virtualPayCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        }else if (yktNewBalance >= 0) {
            virtualPayCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            virtualPayCard.setYktAccountbalance(yktNewBalance);
            orderDTO.setYktMoney(realFee - bzBalance);
            payCardRepository.update(virtualPayCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, virtualPayCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;

        }else if (newBalance >= 0) {
            virtualPayCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            virtualPayCard.setYktAccountbalance(0L);
            orderDTO.setYktMoney(yktBalance);
            virtualPayCard.setAccountbalance(newBalance);
            orderDTO.setMoney(realFee - bzBalance - yktBalance);
            payCardRepository.update(virtualPayCard);

            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,null, virtualPayCard.getId());
            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        } else if (wxNewBalance >= 0) {
            virtualPayCard.setYktAccountbalance(0L);
            orderDTO.setYktMoney(yktBalance);
            virtualPayCard.setAccountbalance(0L);
            orderDTO.setMoney(balance);
            virtualPayCard.setBzAccountbalance(0L);
            orderDTO.setBzMoney(bzBalance);
            virtualPayCard.setWxAccountbalance(wxNewBalance);
            orderDTO.setWxMoney(realFee - bzBalance - yktBalance - balance);
            payCardRepository.update(virtualPayCard);
            OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS, null, virtualPayCard.getId());

            if (discountOrder != null) {
                orderVO.setNote(discountOrder.getNote());
            }
            return orderVO;
        } else {
            throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
            /*//开启免密支付 && contractId不为空，进行免密支付
            if(payCard.getIsnopasswordpay() && payCard.getContractId() != null) {
                try {
                    wxPayService.pappay(orderDTO.getOrderNo(), orderDTO.getRealFee() + "", ip, payCard.getContractId());
                    OrderVO orderVO = this._createOrder(orderDTO, PayStatus.PAYING, null, payCard.getId());

                    if (discountOrder != null) {
                        orderVO.setNote(discountOrder.getNote());
                    }

                    return orderVO;
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new ServiceException(WX_CONTRACT_PAY_ERROR);
                }

            } else {
                throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
            }*/
        }

    }

    public void saveIntranetOrder(List<IntranetOrderForm> intranetOrderFormList,String ipAddress){
        for (IntranetOrderForm intranetOrderForm : intranetOrderFormList){
            BinguoOrder binguoOrder = intranetOrderForm.getBinguoOrder();
            binguoOrder.setId(null);
            binguoOrderRepository.save(binguoOrder);
            List<OrderItem> orderItemList = intranetOrderForm.getOrderItems();
            for (OrderItem orderItem : orderItemList){
                orderItem.setId(null);
                orderItemRepository.save(orderItem);
            }

            PayCard payCard = payCardRepository.findById(binguoOrder.getId());
            Long realFee = binguoOrder.getRealfee();

            Long balance = payCard.getAccountbalance();
            Long wxBalance = payCard.getWxAccountbalance();
            Long yktBalance = payCard.getYktAccountbalance();
            Long bzBalance = payCard.getBzAccountbalance();

            Long bzNewBalance = bzBalance - realFee;
            Long yktNewBalance = yktBalance - realFee+ bzBalance;
            Long wxNewBalance = wxBalance - realFee + yktBalance + bzBalance;
            Long newBalance = balance - realFee + yktBalance + bzBalance + wxBalance;

            if (bzNewBalance >= 0){
                payCard.setBzAccountbalance(bzNewBalance);
            }else if (yktNewBalance >= 0) {
                payCard.setBzAccountbalance(0L);
                payCard.setYktAccountbalance(yktNewBalance);
            }else if (wxNewBalance >= 0) {
                payCard.setBzAccountbalance(0L);
                payCard.setYktAccountbalance(0L);
                payCard.setWxAccountbalance(wxNewBalance);
            } else{
                payCard.setYktAccountbalance(0L);
                payCard.setBzAccountbalance(0L);
                payCard.setWxAccountbalance(0L);
                payCard.setAccountbalance(newBalance);
            }
            payCardRepository.update(payCard);
        }
    }

    public void updateIntranetOrderImg(List<IntranetOrderImgForm> intranetOrderImgFormList){
        for (IntranetOrderImgForm form : intranetOrderImgFormList){
            Condition condition = new Condition(BinguoOrder.class);
            condition.or().andEqualTo("orderno",form.getOrderNo())
                    .andEqualTo("serialnumber",form.getSerialNumber())
                    .andEqualTo("shopid",form.getShopId());
            List<BinguoOrder> binguoOrderList = binguoOrderRepository.findByCondition(condition);
            if(binguoOrderList != null && binguoOrderList.size() > 0) {
                BinguoOrder binguoOrder = binguoOrderList.get(0);
                /*StringBuffer outputFilepathStringBuffer = new StringBuffer("/usr/local/nginx/html/images/order/")
                    .append(binguoOrder.getShopid());*/

                StringBuffer outputFilepathStringBuffer = new StringBuffer("C:/Program Files (x86)/apache-tomcat-8.5.47/webapps/ROOT/order/")
                        .append(binguoOrder.getShopid());

                File dirOutput = new File(outputFilepathStringBuffer.toString());
                if (!dirOutput.exists()) {
                    dirOutput.mkdir();
                }
                String newFileName = outputFilepathStringBuffer.append("/").append(binguoOrder.getSerialnumber()).append(".png").toString();

                /*String httpFileName = new StringBuffer("http://")
                    .append(ipAddress)
                    .append(":8019/images/order/")
                    .append(binguoOrder.getShopid()).append("/").append(binguoOrder.getSerialnumber()).append(".png").toString();*/

                String httpFileName = new StringBuffer("http://")
                        .append("123.206.224.209")
                        .append(":8080/")
                        .append("order/")
                        .append(binguoOrder.getShopid()).append("/").append(binguoOrder.getSerialnumber()).append(".png").toString();
                ImageBase64Util.base64StringToImage(form.getOrderImgBase64(), newFileName);
                orderService.saveOrderUrl(binguoOrder.getSerialnumber(),binguoOrder.getShopid(), httpFileName);
            }
        }
    }

    public OrderVO createPhysicalCardOrder(OrderDTO orderDTO, Shop shop) {
        this._updatePhysicalCard(orderDTO, shop);
        return this._createOrder(orderDTO, PayStatus.SUCCESS);
    }



    public OrderVO createQrcodeOrder(OrderDTO orderDTO, String ip) {
        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.PAYING);


        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());
            orderVO.setNote(discountOrder.getNote());
        }

        String wxqrCode = "https://binguoai.com/api/wxpay/doPay?orderNo=" + orderDTO.getOrderNo() + "&totalFee=" + orderDTO.getRealFee();

        String aliqrCode = aliPayService.zfbQrCode(orderDTO.getOrderNo(), orderDTO.getRealFee(), orderDTO.getOrderNo());

        //二维码跳转url, 客户端根据url生成二维码
        String qrCode = "https://www.binguoai.com/api/qrcode?wxqrcode=" + wxqrCode + "&aliqrcode=" + aliqrCode;
        orderVO.setQrCode(qrCode);
        return orderVO;
    }


    public OrderVO createQrcodeOrderForServerPay(OrderDTO orderDTO, String ip) {
        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.PAYING);

        Shop shop = shopService.findShopById(orderDTO.getShopId());


        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());
            orderVO.setNote(discountOrder.getNote());
        }

        //服务商支付使用统一下单返回的支付url地址
        String wxqrCode = wxServerPayService.unifiedOrder(orderDTO.getOrderNo(), orderDTO.getRealFee(),
                ip, shop.getSubAppid(), shop.getSubMchId());

        String aliqrCode = aliPayService.zfbQrCode(orderDTO.getOrderNo(), orderDTO.getRealFee(), orderDTO.getOrderNo());

        //二维码跳转url, 客户端根据url生成二维码
        String qrCode = "https://www.binguoai.com/api/qrcode?wxqrcode=" + wxqrCode + "&aliqrcode=" + aliqrCode;
        orderVO.setQrCode(qrCode);
        return orderVO;
    }


    @Transactional
    public OrderVO _createOrder(OrderDTO orderDTO, PayStatus payStatus) {
        return _createOrder(orderDTO, payStatus, null, null);
    }

    @Transactional
    public OrderVO  _createOrder(OrderDTO orderDTO, PayStatus payStatus, String transactionId, Integer cardId) {
        return _createOrder(orderDTO, payStatus, transactionId, cardId, null,null);
    }

    @Transactional
    public OrderVO  _createOrder(OrderDTO orderDTO,
                                 PayStatus payStatus,
                                 String transactionId,
                                 Integer cardId,
                                 String yiLingTraceNum,
                                 String srDate) {
        long s17 = System.currentTimeMillis();
        logger.info("s17=" + s17);
        String serial = "";
//        Optional<BinguoOrder> binguoOrderOptional = orderService.findLastOrder(orderDTO.getShopId(), orderDTO.getCashierDeskId());
//        if (binguoOrderOptional.isPresent()) {
//            serial = CommonUtil.plusSerial(binguoOrderOptional.get().getSerial());
//        } else {
        serial = orderDTO.getShopId() + "_" + 1;
//        }

        Integer branchId = null;
        if (DataLoadService.cashierDeskBranchMap != null) {
            branchId = DataLoadService.cashierDeskBranchMap.get(orderDTO.getCashierDeskId());
        }

        String orderNo = orderDTO.getOrderNo();
        BinguoOrder order = BinguoOrder.builder()
                .serialnumber(orderDTO.getSerialNumber())
                .orderno(orderNo)
                .shopid(orderDTO.getShopId())
                .cardno(orderDTO.getCardNo())
                .serial(serial)
                .cashierdeskid(orderDTO.getCashierDeskId())
                .openid(orderDTO.getOpenId())
                .customerid(orderDTO.getCustomerId())
                .customername(orderDTO.getCustomerName())
                .customerphone(orderDTO.getCustomerPhone())
                .customergroupid(orderDTO.getCustomerGroupID())
                .source(orderDTO.getPayType().getCode().byteValue())
                .totalfee(orderDTO.getTotalFee())
                .realfee(orderDTO.getRealFee())
                .totalquantity(orderDTO.getTotalQuantity())
                .paystatus(payStatus.getCode().byteValue())
                .refundstatus(RefundStatus.UN_REFUND.getCode().byteValue())
                .yilingTradeNum(yiLingTraceNum)
                .productOrderNo(orderDTO.getProductOrderNo())
                .productOrderUrl(orderDTO.getProductOrderUrl())
                .branchid(branchId)
                .money(orderDTO.getMoney())
                .bzMoney(orderDTO.getBzMoney())
                .yktMoney(orderDTO.getYktMoney())
                .wxMoney(orderDTO.getWxMoney())
                .note(orderDTO.getNote())
                .build();

        if (transactionId != null) {
            order.setTransactionid(transactionId);
        }
        if (orderDTO.getPayTime() != null){
            order.setPaytime(orderDTO.getPayTime());
        }
        if (cardId != null) {
            order.setCardid(cardId);
        }
        if (srDate != null){

            logger.info(srDate);
            Date date = null;
            try {
                date = dbCompareDateFormat.parse(srDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            order.setCreated(date);
            order.setOrdertype(5);
        }
        binguoOrderRepository.save(order);


        List<Integer> idList = orderDTO.getItems().stream().map(OrderItemDTO::getProductId).collect(Collectors.toList());

        final Map<Integer, String> productNameMap;
        if (DataLoadService.productNameMap != null) {
            productNameMap = new HashMap<>();
            for (Integer pId : idList) {
                String pName = DataLoadService.productNameMap.get(pId);

                if (pName == null) {
                    Product p = productService.getProductById(pId);
                    if (p != null) {
                        pName = p.getName();
                    }
                }

                productNameMap.put(pId, pName);
            }
        }else {
            List<Product> productList = productService.getProductByIdList(idList);

            productNameMap = productList.stream().collect(Collectors.toMap(Product::getId, Product::getName));
        }

        List<OrderItem> items = orderDTO.getItems().stream().map(item ->
                OrderItem.builder()
                        .orderno(orderNo)
                        .productid(item.getProductId())
                        .productname(productNameMap.get(item.getProductId()))
                        .price(item.getPrice())
                        .realprice(item.getPrice())
                        .quantity(item.getQuantity())
                        .created(new Date())
                        .updated(new Date()).build()
        ).collect(Collectors.toList());
        orderItemRepository.save(items);

        long s18 = System.currentTimeMillis();
        logger.info("s18=" + s18);

        ThreadManager.executorService.submit(() -> {
            orderService.updateOrder(orderDTO);

            Shop shop = null;
            if (DataLoadService.shopMap != null) {
                shop = DataLoadService.shopMap.get(orderDTO.getShopId());
            }
            if (shop == null) {
                shop = shopService.findShopById(orderDTO.getShopId());
            }
            if (shop != null && StringUtils.hasText(shop.getApiServiceClassName())) {
                Object api = SpringUtil.getBean(shop.getApiServiceClassName());
                if (api != null) {
                    ShopApiInterface shopApiInterface = (ShopApiInterface)api;
                    shopApiInterface.payPostHandler(orderDTO);
                }
            }
        });
        return orderService.findOneByOrderNo2(orderDTO.getOrderNo());
    }


    @Transactional
    public OrderVO refund(String orderNo, Long refundFee) {
        Condition condition = new Condition(BinguoOrder.class);
        condition.or().andEqualTo("orderno",orderNo);

        BinguoOrder order = binguoOrderRepository.findByCondition(condition).get(0);
        if (order == null) {
            throw new ServiceException(WX_ORDER_NOT_EXIST);
        }

        Shop shop = shopService.findShopById(order.getShopid());

        if (orderNo.startsWith("Q")) {//用户扫二维码支付订单
            //同时发起两路支付退款
            //发起微信退款,等待通知
            try {
                wxPayService.doRefund(orderNo, order.getRealfee().toString(), refundFee.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }

            //发起支付宝退款,直接更新
            Boolean isSuccess = aliPayService.doRefund(orderNo, refundFee);
            if (isSuccess) {
                updateRefundOrder(orderNo, RefundStatus.REFUDN_OK);
            } else {
                updateRefundOrder(orderNo, RefundStatus.REFUND_FAIL);
            }
        }else if (orderNo.startsWith("C")) {//实体卡订单
            if (shop.getCardPayType() != null && shop.getCardPayType() == 1){
                Long orderMoney = order.getRealfee();
                Long refundMoney = order.getRefundfee();
                if (refundMoney + refundFee > orderMoney){
                    throw new ServiceException("超出退款上限");
                }
                PayCard payCard = _getPayCardById(order.getCardid());
                Long balance = payCard.getAccountbalance();
                Long newBalance = balance + refundFee;

                payCard.setAccountbalance(newBalance);
                payCardRepository.update(payCard);

                order.setRefundfee(refundFee+order.getRefundfee());
                order.setRefundtime(new Date());

                if (refundMoney + refundFee == orderMoney) {
                    order.setRefundstatus(RefundStatus.REFUDN_OK.getCode().byteValue());
                }else {
                    order.setRefundstatus(RefundStatus.PART_REFUDN_OK.getCode().byteValue());
                }
                binguoOrderRepository.update(order);
            }else {
                throw new ServiceException("不支持的退款方式");
            }
        }else if (orderNo.startsWith("SS")) {//微信扫码支付
            //发起微信退款,等待通知
            wxServerPayService.doWxRefund(shop.getSubMchId(), orderNo, order.getRealfee().toString(), refundFee.toString());

        }else if (orderNo.startsWith("SZ") || orderNo.startsWith("Z")) {//支付宝扫码支付、移领支付
            //发起传贝退款
            if (shop.getPayType() == 10){
                Condition wuzhenCondition = new Condition(CashierDeskWuzhen.class);
                wuzhenCondition.or().andEqualTo("cashierdeskid",order.getCashierdeskid());
                List<CashierDeskWuzhen> cashierDeskWuzhenList = cashierDeskWuzhenRepository.findByCondition(wuzhenCondition);
                CashierDeskWuzhen cashierDeskWuzhen = cashierDeskWuzhenList.get(0);
                wuZhenPayService.wuzhenRefund(order.getTransactionid(),cashierDeskWuzhen.getMerchantid(),cashierDeskWuzhen.getDeviceid(),order.getRealfee());
            }
            //发起移领退款
            if (shop.getPayType() == 8 || shop.getPayType() == 4) {
                aliServerPayService.refund(orderNo, shop.getSubAppid(), order.getYilingTradeNum(), PriceUtil.changeF2Y(refundFee), shop.getAliMchId());
            }
            //发起爱宝退款
            if (shop.getPayType() == 15){
                aiBaoPay.payRefund(shop.getShimingkaShopid(), orderNo);
            }

        }else if (orderNo.startsWith("S")) {//第三支付扫码支付
            CashierDesk cashierDesk = cashierDeskRepository.findById(order.getCashierdeskid());
            Boolean aBoolean = wxServerPayService.refund20(order.getRealfee(), order.getTransactionid(), cashierDesk.getCcode());

            order.setRefundfee(refundFee);
            order.setRefundtime(new Date());

            if (aBoolean) {
                order.setRefundstatus(RefundStatus.REFUDN_OK.getCode().byteValue());
            } else {
                order.setRefundstatus(RefundStatus.REFUND_FAIL.getCode().byteValue());
            }
            binguoOrderRepository.update(order);
        }else if (orderNo.startsWith("M") || orderNo.startsWith("F")) {//会员二维码扫码支付、人脸支付
            Long orderMoney = order.getRealfee();
            Long refundMoney = order.getRefundfee();
            if (refundMoney + refundFee > orderMoney){
                throw new ServiceException("超出退款上限");
            }
            PayCard payCard = _getPayCardById(order.getCardid());
            Long balance = payCard.getAccountbalance();
            Long newBalance = balance + refundFee;

            payCard.setAccountbalance(newBalance);
            payCardRepository.update(payCard);

            order.setRefundfee(refundFee+order.getRefundfee());
            order.setRefundtime(new Date());

            if (refundMoney + refundFee == orderMoney) {
                order.setRefundstatus(RefundStatus.REFUDN_OK.getCode().byteValue());
            }else {
                order.setRefundstatus(RefundStatus.PART_REFUDN_OK.getCode().byteValue());
            }
            binguoOrderRepository.update(order);

        }else if (orderNo.startsWith("A")) {//阿里扫码支付
            //发起支付宝退款,直接更新
            Boolean isSuccess = aliPayService.doRefund(orderNo, refundFee);
            if (isSuccess) {
                updateRefundOrder(orderNo, RefundStatus.REFUDN_OK);
            }else {
                updateRefundOrder(orderNo, RefundStatus.REFUND_FAIL);
            }
        }else if (orderNo.startsWith("W")) {//微信扫码支付
            try {
                //发起微信退款,等待通知
                wxPayService.doRefund(orderNo, order.getRealfee().toString(), refundFee.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{//1.0平台旧版本支付
            if (order.getSource() == PayType.QRCODEPAY.getCode().byteValue()) {
                //二维码付款
                //发起微信退款,等待通知
                try {
                    wxPayService.doRefund(orderNo, order.getRealfee().toString(), refundFee.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }

                //发起支付宝退款,直接更新
                Boolean isSuccess = aliPayService.doRefund(orderNo, refundFee);
                if (isSuccess) {
                    updateRefundOrder(orderNo, RefundStatus.REFUDN_OK);
                }
                return orderService.findOneByOrderNo(orderNo);
            }
        }


        return orderService.findOneByOrderNo(orderNo);
    }


    public void aliPaySuccess(String orderNo) {

        Optional<BinguoOrder> orderOptional = orderService.findByPayStatus(orderNo, PayStatus.PAYING);
        if (orderOptional.isPresent()) {
            BinguoOrder binguoOrder = orderOptional.get();
            binguoOrder.setPaystatus(PayStatus.SUCCESS.getCode().byteValue());
            binguoOrder.setPaytime(new Date());
            binguoOrder.setUpdated(new Date());
            binguoOrderRepository.update(binguoOrder);
            //修改payCard的账号余额
        } else {
            throw new ServiceException(WX_ORDER_NOT_EXIST);
        }
    }


    public void wxPaySuccess(String orderNo, String transactionId, String timeEnd) throws ParseException {
        Optional<BinguoOrder> orderOptional = orderService.findByPayStatus(orderNo, PayStatus.PAYING);
        if (orderOptional.isPresent()) {
            BinguoOrder binguoOrder = orderOptional.get();
            binguoOrder.setPaystatus(PayStatus.SUCCESS.getCode().byteValue());
            binguoOrder.setTransactionid(transactionId);
            binguoOrder.setPaytime(simpleDateFormat.parse(timeEnd));
            binguoOrder.setUpdated(new Date());
            binguoOrderRepository.update(binguoOrder);
        } else {
            throw new ServiceException(WX_ORDER_NOT_EXIST);
        }
    }


    public void updateRefundOrder(String orderNo, RefundStatus refundStatus) {
        Optional<BinguoOrder> orderOptional = orderService.findByOrderNo(orderNo);
        if (orderOptional.isPresent()) {
            BinguoOrder binguoOrder = orderOptional.get();
            binguoOrder.setRefundstatus(refundStatus.getCode().byteValue());
            binguoOrderRepository.update(binguoOrder);
        }

    }


    private void _updatePhysicalCard(OrderDTO orderDTO, Shop shop) {
        logger.info("_updatePhysicalCard");
        if (orderDTO.getCustomerId() == null || orderDTO.getCustomerId() == 0){
            logger.info("none customerId");
            return;
        }
        Integer shopID = orderDTO.getShopId();
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("shopid", shopID)
                .andEqualTo("cardtype", CardType.YKT_CARD.getCode().byteValue())
                .andEqualTo("deleted", false)
                .andEqualTo("customerid",orderDTO.getCustomerId());
        Optional<PayCard> payCardOptional = payCardRepository.findByCondition(condition).stream().findFirst();
        //存在更新卡余额
        if (payCardOptional.isPresent()) {
            logger.info("payCardOptional.isPresent");
            PayCard payCard = payCardOptional.get();
            payCard.setYktAccountbalance(orderDTO.getAccountBalance());

            /**
             * 3:自有渠道支付
             * 5:食云集项目自有支付
             * 6:乐天商户支付
             * 7:区政府支付流程
             * 8:金桥支付
             */
            if (shop.getPayType() == 7 && orderDTO.getCustomerId() != null) {
                Customer customer = customerRepository.findById(orderDTO.getCustomerId());
                if (customer != null) {
                    ShopZyParam shopZyParam = shopZyParamRepository.findBy("shopId", shopID);
                    if (shopZyParam != null && shopZyParam.getNetState() != null
                            && shopZyParam.getNetState().intValue() == 1
                    ) {
                        Map<String, Object> result;
                        try {
                            result = zytkService.GetAccInfo(orderDTO.getCardNo(), shopID);
                            String phone = (String) result.get("mobilePhone");
                            String username = (String) result.get("customerName");

                            logger.info(phone);
                            logger.info("username:" + username);
                            logger.info("customer.getName():" + customer.getName());

                            if (username != null) {
                                username = username.trim();
                            }
                            if (customer != null && customer.getName() != null) {
                                customer.setName(customer.getName().trim());
                            }
                            if (customer.getPhone() != null && customer.getPhone().equals(phone)) {
                                logger.info("用户手机号匹配:" + phone);
                            } else {
                                if (customer.getName() != null && customer.getName().equals(username)
                                        && (StringUtils.isEmpty(phone) || StringUtils.isEmpty(phone.trim()))
                                ) {
                                    logger.info("用户姓名匹配:" + username);
                                } else {
                                    logger.info("用户不匹配");
                                    return;
                                }
                            }
                            String name = shop.getName() + "一卡通";
                            payCard.setName(name);

                            String cardno = result.get("cardNo").toString();
                            payCard.setCardno(cardno);

                            String balance = zytkService.GetAccDBMoney(orderDTO.getCardNo(), shopID, ZytkService.cardType);

                            payCard.setYktAccountbalance(Long.valueOf(balance));

                        } catch (Exception e) {
                            logger.info(e.getMessage());

                            return;
                        }
                    } else {
                        return;
                    }

                } else {
                    return;
                }
            }


            if (shop.getPayType() == 8 && orderDTO.getCustomerId() != null) {
                JinQiaoPayCardItem jinQiaoPayCardItem =
                        JinQiaoPayController.GetCardInfoByMemInterface(orderDTO.getCardNo());

                Customer customer = customerRepository.findById(orderDTO.getCustomerId());
                if (customer != null) {
                    if (jinQiaoPayCardItem.getMobilePhone() != null
                            && jinQiaoPayCardItem.getMobilePhone().equals(customer.getPhone())) {
                        logger.info("用户自有卡");
                        payCard.setName(jinQiaoPayCardItem.getTrueName() + "的一卡通");

                        JinQiaoPayCardItem jc = JinQiaoPayController.GetCardInfoByMemInterface(orderDTO.getCardNo());
                        Long balance = jc.getCurrentMoney();
                        payCard.setYktAccountbalance(balance);
                    } else {
                        logger.info("非用户自有卡，退出");
                        return;
                    }
                } else {
                    return;
                }
            }

            if (shop.getPayType() == 6) {
                if (orderDTO.getAccountBalance() > 0) {
                    orderDTO.setAccountBalance(orderDTO.getAccountBalance() - orderDTO.getRealFee());
                    if (orderDTO.getCardNo() != null && orderDTO.getCardNo().length() == 10 && orderDTO.getCardNo().startsWith("1")) {
                        logger.info("乐天二次刷卡流程,用户id:" + orderDTO.getCardNo());
                    } else {
                        logger.info("乐天二维码支付,二次刷卡流程结束");
                        return;
                    }
                } else {
                    orderDTO.setAccountBalance(0l);
                    logger.info("乐天二次刷卡：余额为0");
                }
            }


            payCardRepository.update(payCard);

            orderDTO.setCustomerId(payCard.getCustomerid());
        }else if ((shop.getPayType() == 7 || shop.getPayType() == 8)
                && orderDTO.getCustomerId() != null){
            if (orderDTO.getCustomerId() == null) {
                return;
            }
            if (StringUtils.isEmpty(orderDTO.getCardNo())) {
                return;
            }

            boolean isCreate = false;
            PayCard payCard = null;
            if (true) {
                isCreate = true;
                payCard = PayCard.builder()
                        .shopid(shopID)
                        .customerid(orderDTO.getCustomerId())
                        .cardno(orderDTO.getCardNo())
                        .cardtype(CardType.YKT_CARD.getCode().byteValue())
                        .deleted(false)
                        .build();

                /**
                 * 5:食云集项目自有支付
                 * 6:乐天商户支付
                 * 7:区政府支付流程
                 * 8:金桥支付
                 */

                if (shop.getPayType() == 8) {
                    JinQiaoPayCardItem jinQiaoPayCardItem =
                            JinQiaoPayController.GetCardInfoByMemInterface(orderDTO.getCardNo());

                    Customer customer = customerRepository.findById(orderDTO.getCustomerId());
                    if (customer != null) {
                        if (jinQiaoPayCardItem.getMobilePhone() != null
                                && jinQiaoPayCardItem.getMobilePhone().equals(customer.getPhone())) {
                            logger.info("用户自有卡");
                            payCard.setName(jinQiaoPayCardItem.getTrueName() + "的一卡通");
                        } else {
                            logger.info("非用户自有卡，退出");
                            return;
                        }
                    } else {
                        return;
                    }
                }
                if (shop.getPayType() == 7) {

                    Customer customer = customerRepository.findById(orderDTO.getCustomerId());
                    if (customer != null) {
                        ShopZyParam shopZyParam = shopZyParamRepository.findBy("shopId", shopID);
                        if (shopZyParam != null && shopZyParam.getNetState() != null
                                && shopZyParam.getNetState().intValue() == 1
                        ) {
                            Map<String, Object> result;
                            try {
                                result = zytkService.GetAccInfo(orderDTO.getCardNo(), shopID);
                            } catch (Exception e) {
                                throw new ServiceException(WX_PAYCARD_NOT_EXIST);
                            }

                            String phone = (String) result.get("mobilePhone");
                            String username = (String) result.get("customerName");

                            logger.info(phone);
                            logger.info("username:" + username);
                            logger.info("customer.getName():" + customer.getName());

                            if (username != null) {
                                username = username.trim();
                            }
                            if (customer != null && customer.getName() != null) {
                                customer.setName(customer.getName().trim());
                            }
                            if (customer.getPhone() != null && customer.getPhone().equals(phone)) {
                                logger.info("用户手机号匹配:" + phone);
                            } else {
                                if (customer.getName() != null && customer.getName().equals(username)
                                        && (StringUtils.isEmpty(phone) || StringUtils.isEmpty(phone.trim()))
                                ) {
                                    logger.info("用户姓名匹配:" + username);
                                } else {
                                    logger.info("用户不匹配");
                                    return;
                                }
                            }
                            String name = result.get("customerName") + "的一卡通";
                            payCard.setName(name);

                            payCard.setCardno(result.get("cardNo").toString());
                        } else {
                            return;
                        }
                    } else {
                        return;
                    }
                }
            }

            payCard.setCardtype(CardType.YKT_CARD.getCode().byteValue());
            payCard.setYktAccountbalance(orderDTO.getAccountBalance());
            if (shop.getPayType() == 8) {
                JinQiaoPayCardItem jinQiaoPayCardItem = JinQiaoPayController.GetCardInfoByMemInterface(orderDTO.getCardNo());
                Long balance = jinQiaoPayCardItem.getCurrentMoney();
                payCard.setYktAccountbalance(balance);
                updateJinQiaoCustomer(payCard.getCustomerid(), jinQiaoPayCardItem);
            }

            /**
             * 3:自有渠道支付
             * 5:食云集项目自有支付
             * 6:乐天商户支付
             * 7:区政府支付流程
             * 8:金桥支付
             */
            /*if (shop.getPayType() == 7) {
                String balance = zytkService.GetAccDBMoney(payCard.getCardno(), shopID, ZytkService.cardType);

                payCard.setAccountbalance(Long.valueOf(balance));
            }*/

            if (isCreate) {
                payCardRepository.save(payCard);
            } else {
                payCardRepository.update(payCard);
            }
        }


    }

    private void createYKTCard(Shop shop, Integer customerId, String cardNo){
        logger.info("begin createYKTCard : " + customerId + cardNo);
        if (shop == null || customerId == null) {
            return;
        }
        if (StringUtils.isEmpty(cardNo)) {
            return;
        }

        PayCard temp = _getPayCard(cardNo, customerId);

        if (temp != null && temp.getDeleted().equals(false)) {
            return;
        }

        PayCard payCard = PayCard.builder()
                .shopid(shop.getId())
                .customerid(customerId)
                .cardno(cardNo)
                .cardtype(CardType.YKT_CARD.getCode().byteValue())
                .deleted(false)
                .build();

        /**
         * 5:食云集项目自有支付
         * 6:乐天商户支付
         * 7:区政府支付流程
         * 8:金桥支付
         */

        if (shop.getPayType() == 8) {
            JinQiaoPayCardItem jinQiaoPayCardItem =
                    JinQiaoPayController.GetCardInfoByMemInterface(cardNo);

            Customer customer = customerRepository.findById(customerId);
            if (customer != null) {
                if (jinQiaoPayCardItem.getMobilePhone() != null
                        && jinQiaoPayCardItem.getMobilePhone().equals(customer.getPhone())) {
                    logger.info("用户自有卡");
                    payCard.setName(jinQiaoPayCardItem.getTrueName() + "的一卡通");
                } else {
                    logger.info("非用户自有卡，退出");
                    return;
                }
            } else {
                return;
            }
        }

        payCard.setCardtype(CardType.YKT_CARD.getCode().byteValue());
        if (shop.getPayType() == 8) {
            JinQiaoPayCardItem jinQiaoPayCardItem = JinQiaoPayController.GetCardInfoByMemInterface(cardNo);
            Long balance = jinQiaoPayCardItem.getCurrentMoney();
            payCard.setYktAccountbalance(balance);
            updateJinQiaoCustomer(payCard.getCustomerid(), jinQiaoPayCardItem);
        }

        payCardRepository.save(payCard);
        logger.info("end createYKTCard : " + customerId + cardNo);
    }


    private List<PayCard> _getPayCardList(Integer shopId, Integer customerId) {
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("shopid", shopId)
                .andEqualTo("customerid", customerId);
        return payCardRepository.findByCondition(condition);
    }

    private PayCard _getPayCard(String cardNo, Integer customerId) {
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("cardno", cardNo)
                .andEqualTo("customerid", customerId);
        return payCardRepository.findByCondition(condition).stream().findFirst().orElseThrow(() -> new ServiceException(WX_PAYCARD_NOT_EXIST));
    }


    private PayCard _getPayCardByPayCode(String payCode) {
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("payCode", payCode);
        return payCardRepository.findByCondition(condition).stream().findFirst().orElseThrow(() -> new ServiceException(WX_PAYCARD_NOT_EXIST));
    }

    private PayCard _getPayCardById(Integer id) {
        PayCard payCard = payCardRepository.findById(id);
        if (payCard == null) {
            throw new ServiceException(WX_PAYCARD_NOT_EXIST);
        }

        return payCard;
    }



    @Autowired
    private ShiYunJiService shiYunJiService;

    /**
     * 支付宝服务商B扫C支付
     * @param orderDTO
     * @return
     */
    private OrderVO createShiYunJiPay(OrderDTO orderDTO) {
        DiscountOrderDetail discountOrder = discountService.discount(orderDTO.getShopId(), orderDTO.getCustomerId(), orderDTO.getRealFee(), orderDTO.getCustomerGroupID());

        if (discountOrder != null) {
            orderDTO.setRealFee(discountOrder.getTotalFee());

            if (discountOrder.getTotalFee() == 0) {
                OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);
                orderVO.setNote(discountOrder.getNote());
                return orderVO;
            }
        }

        Boolean isSuccess = shiYunJiService.doPay(orderDTO.getOrderNo(), PriceUtil.changeF2Y(orderDTO.getRealFee()),
                orderDTO.getAuthCode());
        if (!isSuccess) throw new ServiceException(WX_MICROPAY_ERROR);

        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS);

        if (discountOrder != null) {
            orderVO.setNote(discountOrder.getNote());
        }
        return orderVO;
    }

    private OrderVO createChuanBeiPay(OrderDTO orderDTO) {

        Condition condition = new Condition(CashierDeskWuzhen.class);
        condition.or().andEqualTo("cashierdeskid",orderDTO.getCashierDeskId());
        List<CashierDeskWuzhen> cashierDeskWuzhenList = cashierDeskWuzhenRepository.findByCondition(condition);
        Integer merchantId;
        Integer deviceId;
        if (cashierDeskWuzhenList.size() > 0){
            CashierDeskWuzhen cashierDeskWuzhen = cashierDeskWuzhenList.get(0);
            merchantId = cashierDeskWuzhen.getMerchantid();
            deviceId = cashierDeskWuzhen.getDeviceid();
        }else {
            Map<String,Integer> result = wuZhenPayService.deviceActivation(orderDTO.getCashierDeskId());
            merchantId = result.get("merchantId");
            deviceId = result.get("deviceId");
        }
        JSONObject payResult = wuZhenPayService.wuzhenPay(orderDTO.getAuthCode(),orderDTO.getRealFee(),merchantId,deviceId);
        if (null == payResult){
            throw new ServiceException(WX_MICROPAY_ERROR);
        }
        String orderID = payResult.getString("orderId");
        OrderVO orderVO = this._createOrder(orderDTO, PayStatus.SUCCESS,orderID,null);
        return orderVO;
    }

    public List<ShangMiOrderVO> getShangMiOrder(Integer limit,Integer cashierDeskID){
        List<BinguoOrder> binguoOrderList = binguoOrderMapper.findShangMiOrder(limit,cashierDeskID);
        List<ShangMiOrderVO> shangMiOrderVOList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        for (BinguoOrder binguoOrder : binguoOrderList){
            ShangMiOrderVO shangMiOrderVO = new ShangMiOrderVO();
            shangMiOrderVO.setOrderNO(binguoOrder.getOrderno());
            shangMiOrderVO.setPrice(PriceUtil.changeF2Y(binguoOrder.getRealfee()));
            shangMiOrderVO.setPayDate(sdf.format(binguoOrder.getPaytime()));
            if (binguoOrder.getSource() == 0) {
                shangMiOrderVO.setPaySourse("二维码");
            }else if (binguoOrder.getSource() == 1){
                shangMiOrderVO.setPaySourse("人脸");
            }else if (binguoOrder.getSource() == 2){
                shangMiOrderVO.setPaySourse("实体卡");
            }else if (binguoOrder.getSource() == 3){
                shangMiOrderVO.setPaySourse("现金");
            }else if (binguoOrder.getSource() == 4){
                if (binguoOrder.getOrderno().startsWith("Z")){
                    shangMiOrderVO.setPaySourse("微信支付");
                }else {
                    shangMiOrderVO.setPaySourse("支付宝支付");
                }
            }
            shangMiOrderVOList.add(shangMiOrderVO);
        }

        return shangMiOrderVOList;
    }

    private Long getRealMoney(String price){
        BigDecimal a1 = new BigDecimal(price);
        BigDecimal b1 = new BigDecimal(Integer.toString(100));
        BigDecimal result = a1.multiply(b1);
        return  result.longValueExact();
    }

    private void updateJinQiaoCustomer(Integer customerID,JinQiaoPayCardItem item){
        Customer customer = customerRepository.findById(customerID);
        customer.setName(item.getShowName());
        customer.setGender(item.getSex().byteValue());
        customer.setPhone(item.getMobilePhone());
        customerRepository.update(customer);
    }

    private String updatezytkCustomer(Integer customerID,String cardNO,Integer shopID){
        Map<String, Object> result;
        try {
            result = zytkService.GetAccInfo(cardNO,shopID);
        } catch (Exception e) {
            throw new ServiceException(WX_PAYCARD_NOT_EXIST);
        }
        Customer customer = customerRepository.findById(customerID);
        customer.setName(result.get("customerName").toString());
        customer.setPhone(result.get("mobilePhone").toString());
        customerRepository.update(customer);
        return result.get("cardNo").toString();
    }

    private Integer getPrice(String price){

        BigDecimal oldPrice = new BigDecimal(price);

        BigDecimal a = new BigDecimal("100");

        return oldPrice.multiply(a).intValue();
    }

    public void zzgFacePay(Integer customerID,
                           Integer shopID,
                           Long realFee) {

        BinguoOrder binguoOrder = new BinguoOrder();
        binguoOrder.setShopid(shopID);
        binguoOrder.setRealfee(realFee);
        binguoOrder.setTotalfee(realFee);
        binguoOrder.setCustomerid(customerID);
        binguoOrder.setOrdertype(12);
        binguoOrder.setSource(new Byte("1"));

        List<PayCard> payCardList = _getPayCardList(shopID, customerID);
        PayCard payCard = payCardList.get(0);

        Long balance = payCard.getAccountbalance();
        Long wxBalance = payCard.getWxAccountbalance();
        Long yktBalance = payCard.getYktAccountbalance();
        Long bzBalance = payCard.getBzAccountbalance();

        Long bzNewBalance = bzBalance - realFee;
        Long yktNewBalance = yktBalance - realFee + bzBalance;
        Long newBalance = balance - realFee + yktBalance + bzBalance;
        Long wxNewBalance = wxBalance - realFee + balance + yktBalance + bzBalance;

        if (bzNewBalance >= 0) {
            payCard.setBzAccountbalance(bzNewBalance);
            binguoOrder.setBzMoney(realFee);
            payCardRepository.update(payCard);
        }else if (yktNewBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            binguoOrder.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(yktNewBalance);
            binguoOrder.setYktMoney(realFee - bzBalance);
            payCardRepository.update(payCard);
        }else if (newBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            binguoOrder.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(0L);
            binguoOrder.setYktMoney(yktBalance);
            payCard.setAccountbalance(newBalance);
            binguoOrder.setMoney(realFee - bzBalance - yktBalance);
            payCardRepository.update(payCard);
        } else if (wxNewBalance >= 0) {
            payCard.setYktAccountbalance(0L);
            binguoOrder.setYktMoney(yktBalance);
            payCard.setAccountbalance(0L);
            binguoOrder.setMoney(balance);
            payCard.setBzAccountbalance(0L);
            binguoOrder.setBzMoney(bzBalance);
            payCard.setWxAccountbalance(wxNewBalance);
            binguoOrder.setWxMoney(realFee - bzBalance - yktBalance - balance);
            payCardRepository.update(payCard);
        } else {
            throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
        }
        binguoOrderRepository.save(binguoOrder);
    }

    public void zzgHyCodePay(String authCode,
                             Integer shopID,
                             Long realFee){
        PayCard payCard = _getPayCardByPayCode(authCode);

        if (payCard == null) {
            throw new ServiceException(PAYCARD_PAYCODE_INVALID);
        }

        if (payCard.getCardtype().intValue() != 0) {
            throw new ServiceException(PAYCARD_PAYCODE_NOT_SUPPORT);
        }

        if (!payCard.getShopid().equals(shopID)) {
            throw new ServiceException(PAYCARD_PAYCODE_SHOPID_NOT_SUPPORT);
        }

        Date date = payCard.getPayCodeTime();

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -1);

        if (calendar.getTime().after(date)) {
            throw new ServiceException(PAYCARD_PAYCODE_INVALID);
        }


        Long balance = payCard.getAccountbalance();
        Long wxBalance = payCard.getWxAccountbalance();
        Long yktBalance = payCard.getYktAccountbalance();
        Long bzBalance = payCard.getBzAccountbalance();

        Long bzNewBalance = bzBalance - realFee;
        Long yktNewBalance = yktBalance - realFee+ bzBalance;
        Long newBalance = balance - realFee+yktBalance + bzBalance;
        Long wxNewBalance = wxBalance - realFee + balance + yktBalance + bzBalance;

        if (bzNewBalance >= 0 ){
            payCard.setBzAccountbalance(bzNewBalance);
            payCardRepository.update(payCard);
        }else if (yktNewBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            payCard.setYktAccountbalance(yktNewBalance);
            payCardRepository.update(payCard);

        }else if (newBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            payCard.setYktAccountbalance(0L);
            payCard.setAccountbalance(newBalance);
            payCardRepository.update(payCard);
        } else if (wxNewBalance >= 0) {
            payCard.setWxAccountbalance(wxNewBalance);
            payCard.setYktAccountbalance(0L);
            payCard.setAccountbalance(0L);
            payCard.setBzAccountbalance(0L);
            payCardRepository.update(payCard);
        } else {
            throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
        }
    }

    public OrderVO SMKYpPay(String idCard,
                            String customerName,
                            String phoneNo,
                            String shopPaycardid,
                            String cardType,
                            OrderDTO orderDTO){
        Customer customer = customerService.findSMKCustomer(idCard);
        if (customer == null) {
            customer = new Customer();
            customer.setShopPaycardid(shopPaycardid);
            customer.setIdcardNum(idCard);
            customer.setName(customerName);
            customer.setPhone(phoneNo);
            customer.setCustomerType(cardType);
            customerRepository.save(customer);
            customerService.createPayCard(customer.getId(), orderDTO.getShopId());
            throw new ServiceException(WX_MICROPAY_ERROR);
        } else {
            orderDTO.setCustomerId(customer.getId());
            return createYPCardOrder(orderDTO, 0);
        }
    }

    public int getAgeByBirth(Date birthDay) throws ParseException {
        int age = 0;
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) { //出生日期晚于当前时间，无法计算
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }
        int yearNow = cal.get(Calendar.YEAR);  //当前年份
        int monthNow = cal.get(Calendar.MONTH);  //当前月份
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期
        cal.setTime(birthDay);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        age = yearNow - yearBirth;   //计算整岁数
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;//当前日期在生日之前，年龄减一
                }
            } else {
                age--;//当前月份在生日之前，年龄减一
            }
        }
        return age;
    }

    private void checkConsumeCount(OrderDTO orderDTO, Integer customerID){
        if (orderDTO.getConsumeLimitCount() != null) {
            if (orderDTO.getShopPayConfigId() != null) {
                Map<String, Integer> shopPayConfigIdCountMap = (Map<String, Integer>)redisLockService.getKey("c" + customerID.toString());
                if (shopPayConfigIdCountMap == null) {
                    shopPayConfigIdCountMap = new HashMap<>();
                    shopPayConfigIdCountMap.put("p" + orderDTO.getShopPayConfigId(), 1);
                }else {
                    Integer alreadyConsumeCount = shopPayConfigIdCountMap.get("p" + orderDTO.getShopPayConfigId());
                    if (alreadyConsumeCount == null) {
                        shopPayConfigIdCountMap.put("p" + orderDTO.getShopPayConfigId(), 1);
                    }else {
                        if (alreadyConsumeCount.intValue() >= orderDTO.getConsumeLimitCount().intValue()) {
                            throw new ServiceException("超过消费次数");
                        }else {
                            shopPayConfigIdCountMap.put("p" + orderDTO.getShopPayConfigId(), alreadyConsumeCount + 1);
                        }
                    }
                }
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);

                long time = calendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
                redisLockService.setObjectKey("c" + customerID.toString(), shopPayConfigIdCountMap, time);
            }
        }
    }

   /* public OrderProductPriceBackFrom getOrderPrice(JSONObject jsonParam){
        //得到:商品ID，商品序号 数量   productId seq quantity
        //返回:状态码 ，总价，code，realFee，items
        //1.添加商品id集合
        List<LinkedHashMap> item = new ArrayList<>();
        OrderProductPriceBackFrom orderProductPriceBackFrom = new OrderProductPriceBackFrom();
        Collection<Object> items = new ArrayList<Object>();
        items = jsonParam.values();
        Iterator<Object> it = items.iterator();
        while(it.hasNext()){
            item = (ArrayList<LinkedHashMap>) it.next();
        }
        List<OrderProductPriceForm> orderPPF = new ArrayList<>();
        //查询当前时间段所有的商品信息
        List<ProductPrice> list = new ArrayList<>();
        for(LinkedHashMap its :  item){
            OrderProductPriceForm opp = new OrderProductPriceForm();
            opp.setProductId(Integer.parseInt((String) its.get("productId")));
            opp.setQuantity(Integer.parseInt((String) its.get("quantity")) );
            opp.setSeq((String) its.get("seq"));
            ProductPrice p = new ProductPrice();
            p = productPriceMapper.selectByID(Integer.parseInt((String) its.get("productId")));
            list.add(p);
            orderPPF.add(opp);
        }
        orderProductPriceBackFrom.setItems(orderPPF);
        int sum = 0;
        for(int i = 0;i<list.size();i++){
            //添加商品单价单价
            orderProductPriceBackFrom.getItems().get(i).setPrice(Integer.toUnsignedLong(list.get(i).getPrice()));
            //总价
            sum += orderProductPriceBackFrom.getItems().get(i).getPrice()*
                    orderProductPriceBackFrom.getItems().get(i).getQuantity();
        }
        if(list.size()>0){
            orderProductPriceBackFrom.setCode("200");
            orderProductPriceBackFrom.setRealFee(Integer.toUnsignedLong(sum));
        }
        return orderProductPriceBackFrom;
    }*/
}
